Submission #1126442

#TimeUsernameProblemLanguageResultExecution timeMemory
1126442mychecksedadStreet Lamps (APIO19_street_lamps)C++17
40 / 100
5093 ms81856 KiB
#include<bits/stdc++.h> using namespace std; #define ll long long int #define MOD (1000000000+7) #define MOD1 (998244353) #define pb push_back #define all(x) x.begin(), x.end() #define en cout << '\n' #define ff first #define ss second const int NN = 2e6+100, M = 3e5+10, K = 52, MX = 30; #define upd_sz(_v) {if(_v){_v->sum = _v->val * _v->key;_v->sum2 = _v->val;if(_v->left) _v->sum += _v->left->sum;if(_v->right) _v->sum += _v->right->sum;if(_v->left) _v->sum2 += _v->left->sum2;if(_v->right) _v->sum2 += _v->right->sum2;}} // An AVL tree node class Node { public: int key; Node *left; Node *right; int height, sum, sum2, val; }; // A utility function to get the // height of the tree int height(Node *N) { if (N == NULL) return 0; return N->height; } /* Helper function that allocates a new node with the given key and NULL left and right pointers. */ Node* newNode(int key, int val) { Node* node = new Node(); node->key = key; node->left = NULL; node->right = NULL; node->height = 1; // new node is initially node->val = val; node->sum = key * val; node->sum2 = val; // added at leaf return(node); } // A utility function to right // rotate subtree rooted with y // See the diagram given above. Node *rightRotate(Node *y) { Node *x = y->left; Node *T2 = x->right; // Perform rotation x->right = y; y->left = T2; // Update heights y->height = max(height(y->left), height(y->right)) + 1; x->height = max(height(x->left), height(x->right)) + 1; upd_sz(x); upd_sz(y); upd_sz(x); upd_sz(y); // Return new root return x; } // A utility function to left // rotate subtree rooted with x // See the diagram given above. Node *leftRotate(Node *x) { Node *y = x->right; Node *T2 = y->left; // Perform rotation y->left = x; x->right = T2; // Update heights x->height = max(height(x->left), height(x->right)) + 1; y->height = max(height(y->left), height(y->right)) + 1; upd_sz(y); upd_sz(x); upd_sz(y); upd_sz(x); // Return new root return y; } // Get Balance factor of node N int getBalance(Node *N) { if (N == NULL) return 0; return height(N->left) - height(N->right); } // Recursive function to insert a key // in the subtree rooted with node and // returns the new root of the subtree. Node* insert(Node* node, int key, int val) { /* 1. Perform the normal BST insertion */ if (node == NULL) return(newNode(key, val)); if (key < node->key) node->left = insert(node->left, key, val); else if (key >= node->key) node->right = insert(node->right, key, val); /* 2. Update height of this ancestor node */ node->height = 1 + max(height(node->left), height(node->right)); /* 3. Get the balance factor of this ancestor node to check whether this node became unbalanced */ int balance = getBalance(node); // If this node becomes unbalanced, then // there are 4 cases // Left Left Case if (balance > 1 && key < node->left->key) return rightRotate(node); // Right Right Case if (balance < -1 && key >= node->right->key) return leftRotate(node); // Left Right Case if (balance > 1 && key >= node->left->key) { node->left = leftRotate(node->left); return rightRotate(node); } // Right Left Case if (balance < -1 && key < node->right->key) { node->right = rightRotate(node->right); return leftRotate(node); } upd_sz(node); /* return the (unchanged) node pointer */ return node; } typedef Node* Nodep; int query(Nodep p, int key){ int val = 0; while(p){ if(p->key <= key){ val += p->val * key - p->val * p->key; if(p->left) val += p->left->sum2 * key - p->left->sum; p = p->right; }else{ p = p->left; } } return val; } inline void dfs(Nodep t){ if(!t) return; if(t->left) dfs(t->left); if(t->right) dfs(t->right); free(t); } int n, q, ans[M]; string s; Nodep T[NN]; inline void build(int l, int r, int k){ if(l == r){ T[k] = NULL; return; } int m = l+r>>1; build(l, m, k<<1); build(m+1, r, k<<1|1); T[k] = NULL; } inline void upd(int l, int r, int p, int k, int t1, int t2){ if(!(l == 1 && r == n + 1)){ // Nodep A = new Node(t1, 1); // Nodep B = new Node(t2, -1); // cout << l << ' ' << r << ' ' << t1 << ' ' << t2 << endl; T[k] = insert(T[k], t1, 1); // cout << "wtf" << endl; T[k] = insert(T[k], t2, -1); // cout << l << ' ' << r << ' ' << t1 << ' ' << t2 << endl; } // dfs2(T[k]);en;en; // cout << "insert:" << l << ' ' << r << ' ' << p << ' ' << t1 << ' ' << t2 << '\n'; if(l == r){ return; } int m = l+r>>1; if(p <= m) upd(l, m, p, k<<1, t1, t2); else upd(m+1, r, p, k<<1|1, t1, t2); } inline int get(int l, int r, int p, int k, int tm){ if(l == r){ return query(T[k],tm); } // dfs2(T[k]);en;en; int m = l+r>>1; if(p <= m){ int val = query(T[k<<1|1],tm); return get(l, m, p, k<<1, tm) + val; } return get(m+1, r, p, k<<1|1, tm); } inline void F(int l, int r, int p, int k){ if(l == r){ dfs(T[k]); return; } int m = l+r>>1; if(p <= m) F(l, m, p, k<<1); else F(m+1, r, p, k<<1|1); if(p == r) dfs(T[k]); } vector<array<int, 3>> Q[M]; inline void solve(){ // cout << sizeof(Node) << '\n'; cin >> n >> q >> s; vector<int> val; vector<array<int, 4>> R, QQ; int last = 1; s += '0'; set<array<int, 3>> S; for(int i = 0; i <= n; ++i){ if(s[i] == '0'){ S.insert({last, i + 1, 0}); last = i + 2; } } int qq = 0; for(int i = 0; i < q; ++i){ string x; int a, b; cin >> x; if(x == "toggle"){ cin >> a; --a; if(s[a] == '0'){ s[a] = '1'; ++a; auto it = S.lower_bound(array<int, 3>{a + 1, -1, -1}); assert(it != S.begin()); auto it2 = prev(it); auto x = *it, y = *it2; S.erase(it2); S.erase(S.find(x)); S.insert({y[0], x[1], i + 1}); // check R.pb({x[0], x[1], x[2], i + 1}); R.pb({y[0], y[1], y[2], i + 1}); }else{ s[a] = '0'; ++a; auto it = S.lower_bound(array<int, 3>{a + 1, -1, -1}); assert(it != S.begin()); it = prev(it); auto x = *it; S.erase(it); S.insert({x[0], a, i + 1}); // check S.insert({a + 1, x[1], i + 1}); // check R.pb({x[0], x[1], x[2], i + 1}); } }else{ cin >> a >> b; QQ.pb({a, b, i + 1, qq}); qq++; } } for(auto p: S){ R.pb({p[0], p[1], p[2], q}); } for(auto &p :QQ){ Q[p[0]].pb({p[1], p[2], p[3]}); } S.clear(); sort(all(R)); build(1, n + 1, 1); int p = 0; // for(auto f: R){ // cout << f[0] << ' ' << f[1] << ' ' << f[2] << ' ' << f[3] << '\n'; // } // en;en; for(int l = 1; l <= n; ++l){ while(p < R.size() && R[p][0] == l){ // cout << R[p][0] << ' ' << R[p][1] << ' ' << R[p][2] << ' ' << R[p][3] << endl; // cout << endl; int r = R[p][1], t1 = R[p][2], t2 = R[p][3]; upd(1, n + 1, r, 1, t1, t2); ++p; } for(auto query: Q[l]){ int r = query[0], tm = query[1], idx = query[2]; // cout << l << ' ' << r << endl; ans[idx] = get(1, n + 1, r, 1, tm); // cout << ans[idx] << ' '; // en;en; } // if(l <= n/2) F(1, n + 1, l, 1); } for(int i = 0; i < qq; ++i) cout << ans[i] << '\n'; } int32_t main(){ cin.tie(0); ios::sync_with_stdio(0); int tt = 1, aa; // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while(tt--){ solve(); } cerr<<"time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" seconds\n"; 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...