Submission #739619

#TimeUsernameProblemLanguageResultExecution timeMemory
739619shrimbGame (IOI13_game)C++17
63 / 100
13061 ms169000 KiB
#ifdef MUAATH_5 #include "ioi.h" #else #include "game.h" #endif #include <numeric> #define ll long long #define int long long #define OUT 0 #define merge gcd using namespace std; const int N = 1'000'000'000; const int SZ = 3'500'000; struct ynode { ynode() : val(OUT), left(0), right(0) {} ll val; int left, right; }; struct xnode { xnode() : left(0), right(0), yy(0) {} int left, right; int yy; } root; int yyc = 1, xxc = 1; xnode xnds[SZ]; ynode ynds[SZ]; ll query_y(const int &qy1, const int &qy2, const ynode &node, int l = 0, int r = N - 1) { if (r < qy1 || qy2 < l) return OUT; if (qy1 <= l && r <= qy2) return node.val; const int mid = (l + r) / 2; return merge( (node.left ? query_y(qy1, qy2, ynds[node.left], l, mid) : OUT), (node.right ? query_y(qy1, qy2, ynds[node.right], mid + 1, r) : OUT) ); } ll query_x(const int &qx1, const int &qy1, const int &qx2, const int &qy2, const xnode &node, int l = 0, int r = N - 1) { if (r < qx1 || qx2 < l) return OUT; if (qx1 <= l && r <= qx2) return query_y(qy1, qy2, ynds[node.yy]); const int mid = (l + r) / 2; return merge( (node.left ? query_x(qx1, qy1, qx2, qy2, xnds[node.left], l, mid) : OUT), (node.right ? query_x(qx1, qy1, qx2, qy2, xnds[node.right], mid + 1, r) : OUT) ); } void update_y(const int &qy, const ll &val, ynode &node, int l = 0, int r = N - 1) { if (l == r) { node.val = val; return; } const int mid = (l + r) / 2; if (qy <= mid) { if (!node.left) node.left = yyc++; update_y(qy, val, ynds[node.left], l, mid); } else { if (!node.right) node.right = yyc++; update_y(qy, val, ynds[node.right], mid + 1, r); } node.val = merge((node.left ? ynds[node.left].val : OUT), (node.right ? ynds[node.right].val : OUT)); } void update_x(const int &qx, const int &qy, const ll &val, xnode &node, int l = 0, int r = N - 1) { if (!node.yy) { if (yyc >= SZ) while(1); node.yy = yyc++; } if (l == r) { update_y(qy, val, ynds[node.yy]); return; } const int mid = (l + r) / 2; if (qx <= mid) { if (!node.left) { if (xxc >= SZ) while(1); node.left = xxc++; } update_x(qx, qy, val, xnds[node.left], l, mid); } else { if (!node.right) { if (xxc >= SZ) while(1); node.right = xxc++; } update_x(qx, qy, val, xnds[node.right], mid + 1, r); } update_y(qy, merge( (node.left ? query_y(qy, qy, ynds[xnds[node.left].yy]) : OUT), (node.right ? query_y(qy, qy, ynds[xnds[node.right].yy]) : OUT) ), ynds[node.yy]); } void init(signed R, signed C) { root = xnode(); } void update(signed x, signed y, long long k) { update_x(x, y, k, root); } long long calculate(signed x1, signed y1, signed x2, signed y2) { return query_x(x1, y1, x2, y2, root); }
#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...