Language: C++

#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int arrive = 0;
const int burnout = 1;
const int burning = 2;
const int gfloor = 3;

const int dy[2] = {1, -1};

class Elevator
{
public:
	int dev, cap, v, ts;
	double pos, stime;

	Elevator()
	{}

	Elevator(double pos, double stime, int dev, int cap, int v, int ts)
		:pos(pos),stime(stime),dev(dev),cap(cap),v(v),ts(ts)
	{}
};

class Event
{
public:
	int type, bpos;
	double time;

	Elevator e;

	Event(int type, int bpos, double time)
		:type(type), bpos(bpos), time(time)
	{}

	Event(int type, int bpos, double time, Elevator e)
		:type(type),bpos(bpos),time(time),e(e)
	{}

	bool operator<(const Event& e) const
	{
		return time > e.time;
	}
};

int N,M,K,T[3],devices[33];
bool burn[33];
double D[33];

bool limit(Elevator& e)
{
	return e.cap == e.dev;
}

double arvTime(int dst, Elevator& e, double t)
{
	double res = (max(e.pos, D[dst]) - min(e.pos, D[dst])) / e.v;

	return t + res;
}

Elevator arrived(Event& e)
{
	int n = min(devices[e.bpos], e.e.cap - e.e.dev);
	devices[e.bpos] -= n;

	Elevator res = Elevator(D[e.bpos], e.time+e.e.ts, e.e.dev+n, e.e.cap, e.e.v, e.e.ts);
	return res;
}

Event changeObj(Elevator& e, int d, double t)
{
	double curpos = e.pos;
	double movet = max(e.stime, t);

	if(D[d] > e.pos) curpos += e.v * (movet-e.stime);
	else			 curpos -= e.v * (movet-e.stime);

	bool back = true;

	int dst = 0;
	for(int i = N; i >= 1; i--) {
		if(!burn[i] && devices[i] != 0) {
			dst = i;
			back = false;
			break;
		}
	}

	if(limit(e)) dst = 1;

	e.pos = curpos;
	double arv = arvTime(dst, e, movet);

	int type = arrive;
	if(limit(e) || back) type = gfloor;

	Elevator ne = Elevator(curpos, movet, e.dev, e.cap, e.v, e.ts);
	Event res = Event(type, dst, arv, ne);

	return res;
}

void move(int p, double t, priority_queue<Event>& q)
{
	q.push(Event(burnout, p, t + T[0]));
	for(int i = 0; i < 2; i++) {
		int np = p + dy[i];
		if(np < 1 || np > N) continue;
		if(burn[np]) continue;

		q.push(Event(burning, np, t + T[i+1]));
	}
}

void burned(int p, double t, priority_queue<Event>& q)
{
	if(burn[p]) return;

	burn[p] = true;

	priority_queue<Event> nq;
	while(!q.empty()) {
		Event e = q.top(); q.pop();
		
		if(e.type == arrive) {
			if(e.bpos == p) {
				Event ne = changeObj(e.e, e.bpos, t);
				nq.push(ne);
			}

			else {
				nq.push(e);
			}
			
		}
		if(e.type == burning) {
			if(e.bpos != p)
				nq.push(e);
		}
		if(e.type == burnout) {
			if(e.bpos != p) 
				nq.push(e);
		}
		if(e.type == gfloor) {
			nq.push(e);
		}
	}

	q = nq;
}



void simulate(priority_queue<Event>& q)
{
	memset(burn, 0, sizeof(burn));

	int cnt=0;
	double last=0;

	while(!q.empty()) {
		Event e = q.top(); q.pop();
		if(e.type == arrive) {
			double nt = e.time + e.e.ts;
			q.push(changeObj(arrived(e), e.bpos, nt));

			bool f = burn[e.bpos];
			if(devices[e.bpos] == 0) {
				burned(e.bpos, e.time, q);
				burn[e.bpos] = f;
			}
		}
		if(e.type == burning) {
			move(e.bpos, e.time, q);
		}
		if(e.type == burnout) {
			burned(e.bpos, e.time, q);
		}
		if(e.type == gfloor) {
			if(e.e.dev != 0) {
				
				double nt = e.time + e.e.ts;
				cnt += e.e.dev;
				e.e.dev = 0;
				e.e.pos = D[1];
				e.e.stime = nt;
				last = e.time;

				q.push(changeObj(e.e, e.bpos, nt));
			}
		}
	}

	printf("%d %.3lf\n", cnt, last);
}

int main()
{
	while(cin >> N >> M, (N||M)) {
		int dd;
		cin >> dd;

		D[1] = 0;
		for(int i = 1; i <= N; i++)
			D[i+1] = D[i] + dd;

		for(int i = 1; i <= N; i++)
			cin >> devices[i];

		priority_queue<Event> q;
		for(int i = 0; i < M; i++) {
			int c,v,ts,x;
			cin >> c >> v >> ts >> x;
			Elevator e = Elevator(D[x], 0, 0, c, v, ts);
			q.push(changeObj(e, 1, 0));
		}

		cin >> K >> T[0] >> T[1] >> T[2];
		q.push(Event(burnout, K, T[0]));
		if(K+1 <= N) q.push(Event(burning, K+1, T[1]));
		if(K-1 >= 2) q.push(Event(burning, K-1, T[2]));

		simulate(q);
	}
}

Compiler output:
a.cc: In function 'void simulate(std::priority_queue<Event>&)':
a.cc:170:49: error: cannot bind non-const lvalue reference of type 'Elevator&' to an rvalue of type 'Elevator'
  170 |                         q.push(changeObj(arrived(e), e.bpos, nt));
      |                                          ~~~~~~~^~~
a.cc:75:27: note:   initializing argument 1 of 'Event changeObj(Elevator&, int, double)'
   75 | Event changeObj(Elevator& e, int d, double t)
      |                 ~~~~~~~~~~^