제출 #516877

#제출 시각아이디문제언어결과실행 시간메모리
516877blue가로등 (APIO19_street_lamps)C++17
0 / 100
141 ms5324 KiB
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <set> using namespace std; using vi = vector<int>; using vvi = vector<vi>; using pii = pair<int, int>; using vpii = vector<pii>; const int mx = 300'000; int n, q; int s[1+mx]; set<int> offpoints; int Z = (1<<19); struct stamp_tree { vi stamp = vi(Z<<1, 0); void set(int l, int r, int t) { l += Z; r += Z+1; while(l < r) { if(l & 1) stamp[l++] = t; if(r & 1) stamp[--r] = t; l >>= 1; r >>= 1; } } int query(int i) { int ans = 0; for(i += Z; i >= 1; i >>= 1) ans = max(ans, stamp[i]); return ans; } }; stamp_tree stt; struct col_tree { int l; int r; int lp = 0; col_tree* left = NULL; col_tree* right = NULL; col_tree() { ; } col_tree(int L, int R) { l = L; r = R; } void add(int L, int R, int V) { // cerr << "col add\n"; if(R < l || r < L) return; else if(L <= l && r <= R) { lp += V; } else { if(L <= (l+r)/2) { if(left == NULL) left = new col_tree(l, (l+r)/2); left->add(L, R, V); } if(R >= (l+r)/2+1) { if(right == NULL) right = new col_tree((l+r)/2+1, r); right->add(L, R, V); } } } int query(int I) { // cerr << "col query\n"; if(l == r) return lp; else if(I <= (l+r)/2) { if(left == NULL) return lp; else return lp + left->query(I); } else { if(right == NULL) return lp; else return lp + right->query(I); } } }; struct row_tree { int l; int r; col_tree v; row_tree* left = NULL; row_tree* right = NULL; row_tree() { ; } row_tree(int L, int R) { l = L; r = R; v = col_tree(1, n); if(l == r) return; left = new row_tree(l, (l+r)/2); right = new row_tree((l+r)/2+1, r); } int query(int I, int J) { if(l == r) return v.query(J); else if(I <= (l+r)/2) return v.query(J) + left->query(I, J); else return v.query(J) + left->query(I, J); } void add(int L, int R, int X, int Y, int V) { if(L <= l && r <= R) v.add(X, Y, +1); else if(R < l || r < L) return; else { left->add(L, R, X, Y, V); right->add(L, R, X, Y, V); } } }; row_tree S; int get_value(int l, int r) { return S.query(l, r); } void range_add(int l, int r, int x, int y, int v) { S.add(l, r, x, y, v); } void add_triangle(int l, int r, int t) { stt.set(l, r, t); } void remove_triangle(int l, int r, int t) { int tt = stt.query(l); range_add(l, r, l, r, t - tt); } void switch_on(int i, int t) { offpoints.erase(i); auto it = offpoints.lower_bound(i); int r = *it; it--; int l = *it; remove_triangle(l+1, i-1, t); remove_triangle(i+1, r-1, t); add_triangle(l+1, r-1, t); } void switch_off(int i, int t) { auto it = offpoints.lower_bound(i); int r = *it; it--; int l = *it; offpoints.insert(i); remove_triangle(l+1, r-1, t); add_triangle(l+1, i-1, t); add_triangle(i+1, r-1, t); } int query(int l, int r, int t) { int y = *offpoints.lower_bound(l); if(y > r) return get_value(l, r) + t - stt.query(l); else return get_value(l, r); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> q; string t; cin >> t; for(int i = 0; i < n; i++) s[i+1] = (t[i] == '1'); for(int i = 1; i <= n; i++) if(s[i] == 0) offpoints.insert(i); offpoints.insert(0); offpoints.insert(n+1); S = row_tree(1, n); for(int j = 1; j <= q; j++) { string qr; cin >> qr; if(qr == "toggle") { int i; cin >> i; if(s[i] == 0) { s[i] = 1; switch_on(i, j); } else { s[i] = 0; switch_off(i, j); } } else { int a, b; cin >> a >> b; cout << query(a, b-1, j) << '\n'; } } }
#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...