# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
739606 | Muaath_5 | Game (IOI13_game) | C++17 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "ioi.h"
#include <numeric>
#define ll long long
#define OUT 0
#define merge gcd
using namespace std;
const int N = 1'000'000'000;
const int SZ = 200'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) 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) node.left = xxc++;
update_x(qx, qy, val, xnds[node.left], l, mid);
}
else {
if (!node.right) 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(int R, int C) { root = xnode(); }
void update(int x, int y, long long k) { update_x(x, y, k, root); }
long long calculate(int x1, int y1, int x2, int y2) { return query_x(x1, y1, x2, y2, root); }