Submission #123460

#TimeUsernameProblemLanguageResultExecution timeMemory
123460youngyojunTwo Dishes (JOI19_dishes)C++11
100 / 100
8205 ms191964 KiB
#include <bits/stdc++.h> #define eb emplace_back #define sz(V) ((int)(V).size()) #define allv(V) ((V).begin()),((V).end()) #define sorv(V) sort(allv(V)) #define rb(x) ((x)&(-(x))) using namespace std; typedef long long ll; typedef pair<int, int> pii; const int MAXN = 1000055; const int MAXM = 1000055; struct BIT { ll d[MAXN]; void upd(int x, ll r) { for(x += 5; x < MAXN; x += rb(x)) d[x] += r; } ll get(int x) { ll r = 0; for(x += 5; x; x -= rb(x)) r += d[x]; return r; } ll get(int s, int e) { return s > e ? 0 : get(e) - get(s-1); } } bit; struct NOD { NOD(int i, int s, int e) : i(i), s(s), e(e) {} int i, s, e; }; struct SEG { ll ds[MAXN*3]; bitset<MAXN*3> dz; void prop(int i, int s, int e) { if(dz[i]) { ds[i] = 0; if(s != e) dz[i<<1] = dz[i<<1|1] = true; dz[i] = false; return; } if(s == e) return; ds[i] = 0; if(!dz[i<<1]) ds[i] += ds[i<<1]; if(!dz[i<<1|1]) ds[i] += ds[i<<1|1]; } void cal(int i) { ds[i] = ds[i<<1] + ds[i<<1|1]; } void updz(int i, int s, int e, int p, int q) { prop(i, s, e); if(q < p || e < p || q < s) return; if(p <= s && e <= q) { dz[i] = true; prop(i, s, e); return; } int m = (s+e) >> 1; updz(i<<1, s, m, p, q); updz(i<<1|1, m+1, e, p, q); cal(i); } void updp(int i, int s, int e, int x, ll r) { prop(i, s, e); if(x < s || e < x) return; if(s == e) { ds[i] = r; return; } int m = (s+e) >> 1; updp(i<<1, s, m, x, r); updp(i<<1|1, m+1, e, x, r); ds[i] = ds[i<<1] + ds[i<<1|1]; } void upddx(int i, int s, int e, int x, ll r) { prop(i, s, e); if(x < s || e < x) return; if(s == e) { ds[i] += r; return; } int m = (s+e) >> 1; upddx(i<<1, s, m, x, r); upddx(i<<1|1, m+1, e, x, r); cal(i); } ll get(int i, int s, int e, int p, int q) { prop(i, s, e); if(q < p || e < p || q < s) return 0; if(p <= s && e <= q) return ds[i]; int m = (s+e) >> 1; ll ret = get(i<<1, s, m, p, q) + get(i<<1|1, m+1, e, p, q); cal(i); return ret; } ll get(int i, int s, int e, int x) { return get(1, s, e, x, x); } void getNodes(vector<NOD> &V, int i, int s, int e, int p, int q) { prop(i, s, e); if(q < p || e < p || q < s) return; if(p <= s && e <= q) { V.eb(i, s, e); return; } int m = (s+e) >> 1; getNodes(V, i<<1, s, m, p, q); getNodes(V, i<<1|1, m+1, e, p, q); } int getX(int i, int s, int e, ll lft) { prop(i, s, e); if(s == e) return s; int m = (s+e) >> 1; int ret; if(lft < ds[i<<1]) { ret = getX(i<<1, s, m, lft); prop(i<<1|1, m+1, e); } else { prop(i<<1, s, m); ret = getX(i<<1|1, m+1, e, lft - ds[i<<1]); } cal(i); return ret; } } seg; vector<pii> PopEV[MAXM]; vector<pii> PushEV[MAXM]; ll SA[MAXN], SB[MAXM]; int FI[MAXN], GI[MAXM]; ll C[MAXN], D[MAXM]; int A[MAXN], B[MAXM]; int E[MAXN], F[MAXM]; ll Delta; int N, M; int fndX(int s, ll K) { vector<NOD> V; seg.getNodes(V, 1, 1, N, s, N); ll sum = 0; for(auto &v : V) { ll t = seg.ds[v.i]; if(K <= sum+t) return seg.getX(v.i, v.s, v.e, K-sum); sum += t; } return N+1; } int main() { ios::sync_with_stdio(false); cin >> N >> M; for(int i = 1; i <= N; i++) cin >> A[i] >> C[i] >> E[i]; for(int i = 1; i <= M; i++) cin >> B[i] >> D[i] >> F[i]; for(int i = 1; i <= N; i++) SA[i] = SA[i-1] + A[i]; for(int i = 1; i <= M; i++) SB[i] = SB[i-1] + B[i]; for(int i = 1; i <= N; i++) FI[i] = int(upper_bound(SB, SB+M+1, C[i]-SA[i])-SB) - 1; for(int i = 1; i <= M; i++) GI[i] = int(upper_bound(SA, SA+N+1, D[i]-SB[i])-SA) - 1; for(int i = 1; i <= N; i++) if(0 <= FI[i] && E[i]) { if(0 < E[i]) { PopEV[FI[i]+1].eb(i, E[i]); bit.upd(i, E[i]); } else { Delta += E[i]; if(FI[i] < M) PushEV[FI[i]+1].eb(i-1, -E[i]); } } for(int i = 1; i <= M; i++) if(0 <= GI[i] && F[i]) { if(0 < F[i]) PushEV[i].eb(GI[i], F[i]); else { Delta += F[i]; if(GI[i] < N) { PopEV[i].eb(GI[i]+1, -F[i]); bit.upd(GI[i]+1, -F[i]); } } } for(int j = 1; j <= M; j++) { for(auto &ev : PopEV[j]) { int i, ei; tie(i, ei) = ev; bit.upd(i, -ei); seg.upddx(1, 1, N, i, ei); } for(auto &ev : PushEV[j]) { int i, ei; tie(i, ei) = ev; Delta += ei; int s = fndX(i+1, ei); ll t = seg.get(1, 1, N, i+1, s-1); seg.updz(1, 1, N, i+1, s-1); if(s <= N) seg.upddx(1, 1, N, s, t-ei); } } cout << bit.get(1, N) + seg.get(1, 1, N, 1, N) + Delta << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...