This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#ifdef MUAATH_5
#include "ioi.h"
#else
#include "game.h"
#endif
#include <numeric>
#define ll long long
#define OUT 0
#define merge gcd
using namespace std;
const int N = 1'000'000'009;
const int SZ = 4'800'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); }
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |