Submission #681057

#TimeUsernameProblemLanguageResultExecution timeMemory
681057nutellaGame (IOI13_game)C++17
80 / 100
3056 ms256000 KiB
#include <bits/stdc++.h> #include "game.h" using namespace std; using ll = long long; constexpr int MAXQ = 22000; #define left lft #define right rght #define gcd my_gcd ll my_gcd(ll a, ll b) { if (!a || !b) return a ^ b; ll c; while ((c = a % b)) { a = b; b = c; } return b; } int R, C; constexpr int M = MAXQ * 30 * 30 + 10; int counter = 1; ll d[M]; int left[M], right[M]; //vector<ll> d{{}}; //vector<int> left{{}}, right{{}}; int st_create(int l, int r) { // d.emplace_back(), left.emplace_back(), right.emplace_back(); return counter++; } void st_update(int v, int i, ll k, int l, int r) { if (l + 1 == r) { d[v] = k; } else { int mid = (l + r) / 2; if (i < mid) { if (!left[v]) { left[v] = st_create(l, mid); } st_update(left[v], i, k, l, mid); } else { if (!right[v]) { right[v] = st_create(mid, r); } st_update(right[v], i, k, mid, r); } d[v] = gcd(d[left[v]], d[right[v]]); } } ll st_query(int v, int lx, int rx, int l, int r) { if (lx >= r || rx <= l) { return 0; } else if (lx <= l && r <= rx) { return d[v]; } else { int mid = (l + r) / 2; ll ans = 0; if (left[v]) { ans = gcd(ans, st_query(left[v], lx, rx, l, mid)); } if (right[v]) { ans = gcd(ans, st_query(right[v], lx, rx, mid, r)); } return ans; } } ll st_query_simple(int v, int i, int l, int r) { if (l + 1 == r) { return d[v]; } else { int mid = (l + r) / 2; ll ans = 0; if (mid > i && left[v]) { ans = gcd(ans, st_query_simple(left[v], i, l, mid)); } if (mid <= i && right[v]) { ans = gcd(ans, st_query_simple(right[v], i, mid, r)); } return ans; } } struct SegmentTree { int st = 0; int left = 0, right = 0; }; constexpr int N = MAXQ * 30 + 10; SegmentTree t[N]; //vector<SegmentTree> t{{}}; int node_counter = 1; int create(int l, int r) { // t[node_counter] = SegmentTree({l, r}); // t.emplace_back(); return node_counter++; } void build_st(int x) { if (!t[x].st) { t[x].st = st_create(0, C); } } ll simple_query(int x, int y) { if (!t[x].st) { return 0; } else { return st_query_simple(t[x].st, y, 0, C); } } void update(int v, int x, int y, ll k, int l, int r) { build_st(v); if (l + 1 == r) { st_update(t[v].st, y, k, 0, C); } else { int mid = (l + r) / 2; if (x < mid) { if (!t[v].left) { t[v].left = create(l, mid); } update(t[v].left, x, y, k, l, mid); } else { if (!t[v].right) { t[v].right = create(mid, r); } update(t[v].right, x, y, k, mid, r); } st_update(t[v].st, y, gcd(simple_query(t[v].left, y), simple_query(t[v].right, y)), 0, C); } } ll query(int v, int lx, int rx, int ly, int ry, int l, int r) { if (l >= rx || lx >= r || !t[v].st) { return 0; } else if (lx <= l && r <= rx) { return st_query(t[v].st, ly, ry, 0, C); } else { int mid = (l + r) / 2; ll ans = 0; if (t[v].left) { ans = gcd(ans, query(t[v].left, lx, rx, ly, ry, l, mid)); } if (t[v].right) { ans = gcd(ans, query(t[v].right, lx, rx, ly, ry, mid, r)); } return ans; } } void init(int R, int C) { ::R = R, ::C = C; create(0, R); } void update(int P, int Q, ll K) { update(1, P, Q, K, 0, R); } ll calculate(int P, int Q, int U, int V) { return query(1, P, U + 1, Q, V + 1, 0, 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...