解法
サゾエさんの並び方に関係なくM人の客の会計の時間は固定される.サゾエさんの会計はその隙間に割り込ませればいい.
つまり,サゾエさんが会計をする時になったらN個のレジで最も早く空くところを求めれば良い.
レジの空く時間をRMQでもって,時間順に各人の行動を更新する.
レジの数Nが大きいが,誰も使わないレジを高々1つしか必要ないのでmin(N, M+1)個のみ考えればよい.
struct RMQ {
typedef long long T;
static const T INF = 1LL<<60;
int N, M;
vector<T> A; vector<int> I;
RMQ(int N_=1): N(N_), M(2<<__lg(max(1, N))), A(N+1, INF), I(M*2, N) {
for (int i=0; i<N; i++) I[i+M] = i;
for (int i=M; --i;) I[i] = I[i*2];
}
RMQ(const vector<T> &v): N(v.size()), M(2<<__lg(N)), A(v), I(M*2, N) {
A.push_back(INF);
for (int i=0; i<N; i++) I[i+M] = i;
for (int i=M; --i;) I[i] = (A[I[i*2+1]] < A[I[i*2]]? I[i*2+1]: I[i*2]);
}
void modify(int i, T v) {
A[i] = v;
for (i=(i+M)/2; i>=1; i/=2)
I[i] = (A[I[i*2+1]] < A[I[i*2]]? I[i*2+1]: I[i*2]);
}
int min_i(int x, int y) { return min_i(x, y, 1, 0, M); }
int min_i(int x, int y, int k, int l, int r) {
if (r<=x || y<=l) return N;
if (x<=l && r<=y) return I[k];
int p = min_i(x, y, 2*k, l, (l+r)/2), q = min_i(x, y, 2*k+1, (l+r)/2, r);
return (A[q] < A[p]? q: p);
}
T min_v(int x, int y) { return A[min_i(x, y, 1, 0, M)]; }
};
const RMQ::T RMQ::INF;
LL N;
int M, K, D, S;
int A[100011], B[100011], C[100011];
map<int, int> mp;
int getR(LL x) {
if (mp.count(x) == 0) mp.insert(make_pair(x, mp.size()));
return mp[x];
}
int main() {
scanf("%lld%d%d%d%d", &N, &M, &K, &D, &S);
int cnt = 0;
LL wait = S + D;
REP (i, M) {
LL x;
scanf("%d%d%lld", A+i, B+i, &x);
C[i] = getR(x);
}
int L = min(N, (LL)M + 1);
RMQ rmq(vector<LL>(L, 0));
for (int i=0; cnt<K; cnt++) {
while (i<M && A[i] <= wait) {
LL t = rmq.min_v(C[i], C[i]+1);
rmq.modify(C[i], max(t, (LL)A[i]) + B[i]);
i++;
}
{
LL t = rmq.min_v(0, L);
wait = max(t, wait) + D;
}
}
printf("%lld\n", wait - S - D);
return 0;
}