Submission #1246587

#TimeUsernameProblemLanguageResultExecution timeMemory
1246587aykhnGame (IOI13_game)C++20
10 / 100
448 ms321536 KiB
#include "game.h" #include <bits/stdc++.h> using namespace std; // We’ll use std::gcd on long long // (C++17 <numeric> is included via <bits/stdc++.h>) struct NodeY { long long val = 0; NodeY *l = nullptr, *r = nullptr; }; struct NodeX { NodeX *l = nullptr, *r = nullptr; NodeY *treeY = nullptr; }; int n, m; NodeX* root = nullptr; // Merge two Y‑trees over [ly, ry], return a newly built tree NodeY* mergeY(NodeY* A, NodeY* B, int ly, int ry) { if (!A && !B) return nullptr; NodeY* node = new NodeY(); if (ly == ry) { long long va = A ? A->val : 0; long long vb = B ? B->val : 0; node->val = std::gcd(va, vb); return node; } int my = (ly + ry) >> 1; node->l = mergeY(A ? A->l : nullptr, B ? B->l : nullptr, ly, my); node->r = mergeY(A ? A->r : nullptr, B ? B->r : nullptr, my+1, ry); long long vl = node->l ? node->l->val : 0; long long vr = node->r ? node->r->val : 0; node->val = std::gcd(vl, vr); return node; } // Point‐set update on Y‑tree at fixed X‑node void updateY(NodeY*& node, int ly, int ry, int y, long long v) { if (!node) node = new NodeY(); if (ly == ry) { node->val = v; return; } int my = (ly + ry) >> 1; if (y <= my) updateY(node->l, ly, my, y, v); else updateY(node->r, my+1, ry, y, v); long long vl = node->l ? node->l->val : 0; long long vr = node->r ? node->r->val : 0; node->val = std::gcd(vl, vr); } // Update X‑tree: set a[x][y]=v void updateX(NodeX*& node, int lx, int rx, int x, int y, long long v) { if (!node) node = new NodeX(); if (lx == rx) { // leaf in X: just update its Y‑tree updateY(node->treeY, 0, m-1, y, v); return; } int mx = (lx + rx) >> 1; if (x <= mx) updateX(node->l, lx, mx, x, y, v); else updateX(node->r, mx+1, rx, x, y, v); // after children are updated, merge their Y‑trees node->treeY = mergeY( node->l ? node->l->treeY : nullptr, node->r ? node->r->treeY : nullptr, 0, m-1 ); } // GCD query on a single Y‑tree long long queryY(NodeY* node, int ly, int ry, int y1, int y2) { if (!node || ry < y1 || ly > y2) return 0; if (y1 <= ly && ry <= y2) return node->val; int my = (ly + ry) >> 1; return std::gcd( queryY(node->l, ly, my, y1, y2), queryY(node->r, my+1, ry, y1, y2) ); } // Submatrix GCD query on [x1,x2]×[y1,y2] long long queryX(NodeX* node, int lx, int rx, int x1, int x2, int y1, int y2) { if (!node || rx < x1 || lx > x2) return 0; if (x1 <= lx && rx <= x2) { // fully covered in X → query its Y‑tree return queryY(node->treeY, 0, m-1, y1, y2); } int mx = (lx + rx) >> 1; return std::gcd( queryX(node->l, lx, mx, x1, x2, y1, y2), queryX(node->r, mx+1, rx, x1, x2, y1, y2) ); } // game.h interface void init(int R, int C) { n = R; m = C; root = nullptr; } void update(int P, int Q, long long K) { // set a[P][Q] = K updateX(root, 0, n-1, P, Q, K); } long long calculate(int P, int Q, int U, int V) { // query GCD on [P..U]×[Q..V] return queryX(root, 0, n-1, P, U, Q, V); }
#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...