Submission #50893

#TimeUsernameProblemLanguageResultExecution timeMemory
50893faishol27Sterilizing Spray (JOI15_sterilizing)C++14
100 / 100
1527 ms307412 KiB
//////////////////////////////////////////////// // // // Author: Muhammad Faishol Amirul Mukminin // // // //////////////////////////////////////////////// #include <bits/stdc++.h> using namespace std; typedef long long ll; #define PUB push_back #define POF pop_front const int MAXE = 4e5+5; struct child{ deque<ll>sum; int pending; }; int N, Q, K; int plate[100005]; child segtree[MAXE]; ll ans; void push_pending(int ind, int l, int r){ if(segtree[ind].pending != 0){ if(l != r){ segtree[2*ind].pending += segtree[ind].pending; segtree[2*ind+1].pending += segtree[ind].pending; } while(segtree[ind].pending > 0 && !segtree[ind].sum.empty() && K > 1){ segtree[ind].sum.POF(); segtree[ind].pending--; } segtree[ind].pending = 0; } } void update_me(int ind, int l, int r){ if(l != r){ int mid = (l+r)/2; push_pending(2*ind, l, mid); push_pending(2*ind+1, mid+1, r); int sz_left = segtree[2*ind].sum.size(), sz_right = segtree[2*ind+1].sum.size(); segtree[ind].sum.clear(); for(int i=0; i < min(sz_left, sz_right); i++){ ll tmp = segtree[2*ind].sum[i]+segtree[2*ind+1].sum[i]; if(tmp > 0) segtree[ind].sum.PUB(tmp); } for(int i = min(sz_left, sz_right); i < max(sz_left, sz_right); i++){ if(i < sz_left && segtree[2*ind].sum[i] > 0) segtree[ind].sum.PUB(segtree[2*ind].sum[i]); if(i < sz_right && segtree[2*ind+1].sum[i] > 0) segtree[ind].sum.PUB(segtree[2*ind+1].sum[i]); } segtree[ind].pending = 0; } } void query1(int ind, int l, int r, int i_src, ll val){ push_pending(ind, l, r); if(l == r){ segtree[ind].sum.clear(); while(val > 0){ segtree[ind].sum.PUB(val); val /= K; if(K==1) break; } segtree[ind].pending = 0; return; } int mid = (l+r)/2; if(i_src <= mid) query1(2*ind, l, mid, i_src, val); else query1(2*ind+1, mid+1, r, i_src, val); update_me(ind, l, r); } void query2(int ind, int l, int r, int l_src, int r_src){ if(r < l_src || l > r_src) return; push_pending(ind, l, r); if(l_src <= l && r <= r_src){ segtree[ind].pending += 1; return; } int mid = (l+r)/2; query2(2*ind, l, mid, l_src, r_src); query2(2*ind+1, mid+1, r, l_src, r_src); update_me(ind, l, r); } void query3(int ind, int l, int r, int l_src, int r_src){ push_pending(ind, l, r); if(r < l_src || l > r_src) return; if(l_src <= l && r <= r_src){ if(!segtree[ind].sum.empty()) ans += segtree[ind].sum.front(); return; } int mid = (l+r)/2; query3(2*ind, l, mid, l_src, r_src); query3(2*ind+1, mid+1, r, l_src, r_src); update_me(ind, l, r); } void build_segtree(int ind, int l, int r){ if(l == r){ ll tmp = plate[l]; while(tmp > 0){ segtree[ind].sum.PUB(tmp); tmp /= K; if(K == 1) break; } segtree[ind].pending = 0; return; } int mid = (l+r)/2; build_segtree(2*ind, l, mid); build_segtree(2*ind+1, mid+1, r); int sz_left = segtree[2*ind].sum.size(), sz_right = segtree[2*ind+1].sum.size(); for(int i=0; i < min(sz_left, sz_right); i++){ segtree[ind].sum.PUB(segtree[2*ind].sum[i]+segtree[2*ind+1].sum[i]); } for(int i = min(sz_left, sz_right); i < max(sz_left, sz_right); i++){ if(i < sz_left) segtree[ind].sum.PUB(segtree[2*ind].sum[i]); if(i < sz_right) segtree[ind].sum.PUB(segtree[2*ind+1].sum[i]); } segtree[ind].pending = 0; } void print_segtree(int ind){ cerr << ind << " ->"; for(auto elm:segtree[ind].sum) cerr << " " << elm ; cerr << endl; } ll BF(int id, ll a, ll b){ ll ret = 0; if(id == 1) plate[a] = b; else if(id == 2){ for(int i=a;i<=b;i++) plate[i] /= K; }else{ for(int i=a;i<=b;i++) ret += plate[i]; } return ret; } void debug_segtree(int ind, int l, int r){ print_segtree(ind); push_pending(ind, l, r); print_segtree(ind); ll hr = 0, st = -1; for(int i=l;i<=r;i++) hr += plate[i]; if(!segtree[ind].sum.empty()) st = segtree[ind].sum.front(); if(hr != st) cout << "B " << ind << " " << l << "-" << r << " -> " << hr << " " << st << " " << segtree[ind].pending << endl; else if(hr == st) cout <<l << "-" << r << " -> " << hr << endl; if(l == r) return; int mid = (l+r)/2; debug_segtree(2*ind, l, mid); debug_segtree(2*ind+1, mid+1, r); update_me(ind, l, r); } int main(){ cin >> N >> Q >> K; for(int i=1;i<=N;i++) cin >> plate[i]; build_segtree(1, 1, N); while(Q--){ int id; ll a, b; cin >> id >> a >> b; if(id == 1){ query1(1, 1, N, a, b); }else if(id == 2){ query2(1, 1, N, a, b); }else{ ans = 0; query3(1, 1, N, a, b); cout << ans << 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...