Submission #863384

#TimeUsernameProblemLanguageResultExecution timeMemory
863384deepaung게임 (IOI13_game)C++14
100 / 100
5378 ms67616 KiB
#include <bits/stdc++.h> #include "game.h" #define f first #define s second #define pll pair<ll, ll> #define ll long long using namespace std; mt19937 rnd(time(NULL)); ll R, C; ll gcd2(ll X, ll Y) { ll tmp; while (X != Y && Y != 0) { tmp = X; X = Y; Y = tmp % Y; } return X; } struct Treap { struct node { ll val, gcd, sz, pri; pll pos; node *l, *r; node(ll val=0, pll pos={0, 0}, node *l=NULL, node *r=NULL) : val(val), gcd(val), sz(1), pri(rnd()), pos(pos), l(l), r(r) {} }; node *root; Treap() : root(NULL) {} void recalc(node *cur) { if (cur == NULL) return; cur->sz = 1; cur->gcd = cur->val; if (cur->l != NULL) cur->sz += cur->l->sz, cur->gcd = gcd2(cur->gcd, cur->l->gcd); if (cur->r != NULL) cur->sz += cur->r->sz, cur->gcd = gcd2(cur->gcd, cur->r->gcd); } void split(node *cur, node *&left, node *&right, pll pos) { if (cur == NULL) { left = right = NULL; return; } if (cur->pos <= pos) { split(cur->r, cur->r, right, pos); left = cur; } else { split(cur->l, left, cur->l, pos); right = cur; } recalc(cur); } void merge(node *&cur, node *left, node *right) { if (left == NULL || right == NULL) { cur = (left != NULL ? left : right); return; } if (left->pri >= right->pri) { merge(left->r, left->r, right); cur = left; } else { merge(right->l, left, right->l); cur = right; } recalc(cur); } void update(ll x, ll y, ll val) { node *left, *mid, *right; split(root, left, mid, {y, x-1}); split(mid, mid, right, {y, x}); delete mid; merge(root, left, new node(val, {y, x})); merge(root, root, right); } ll gcd_range(ll yl, ll yr) { node *left, *mid, *right; split(root, left, mid, {yl, -1}); split(mid, mid, right, {yr+1, -1}); ll ans = (mid != NULL ? mid->gcd : 0); merge(root, left, mid); merge(root, root, right); return ans; } }; struct Segtree { struct node { Treap treap; node *l, *r; node() : treap(Treap()), l(NULL), r(NULL) {} }; node *root; void update(ll x, ll y, ll val, node *&cur, ll l, ll r) { if (cur == NULL) cur = new node(); cur->treap.update(x, y, val); if (l == r) return; ll mid = (l + r) >> 1; if (x <= mid) update(x, y, val, cur->l, l, mid); else update(x, y, val, cur->r, mid+1, r); } ll gcd_range(ll xl, ll yl, ll xr, ll yr, node *cur, ll l, ll r) { if (cur == NULL) return 0; if (xr < l || r < xl) return 0; if (xl <= l && r <= xr) { return cur->treap.gcd_range(yl, yr); } ll mid = (l + r) >> 1; ll resl = gcd_range(xl, yl, xr, yr, cur->l, l, mid); ll resr = gcd_range(xl, yl, xr, yr, cur->r, mid+1, r); return gcd2(resl, resr); // if (xl == l && r == xr) { // return cur->treap.gcd_range(yl, yr); // } // ll mid = (l + r) >> 1; // if (xr <= mid) { // return gcd_range(xl, yl, xr, yr, cur->l, l, mid); // } else if (xl >= mid + 1) { // return gcd_range(xl, yl, xr, yr, cur->r, mid+1, r); // } else { // return gcd2( // gcd_range(xl, yl, mid, yr, cur->l, l, mid), // gcd_range(mid+1, yl, xr, yr, cur->r, mid+1, r) // ); // } } } segtree; void init(int R, int C) { ::R = R; ::C = C; } void update(int x, int y, ll val) { x++, y++; segtree.update(x, y, val, segtree.root, 1, R); } ll calculate(int xl, int yl, int xr, int yr) { xl++, yl++, xr++, yr++; return segtree.gcd_range(xl, yl, xr, yr, segtree.root, 1, R); }
#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...