# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
781089 | caganyanmaz | 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 <bits/stdc++.h>
#include "game.h"
#define pb push_back
#define int int64_t
long long gcd(long long X, long long Y) {
long long tmp;
while (X != Y && Y != 0) {
tmp = X;
X = Y;
Y = tmp % Y;
}
return X;
}
int r, c;
std::vector<int> up(1, -1), down(1, -1), root(1, -1);
std::vector<int> left, right, data;
void push_x(int l, int r, int index)
{
if (r - l == 1)
return;
if (left[index] == -1)
{
left[index] = data.size();
left.pb(-1);
right.pb(-1);
data.pb(0);
}
if (right[index] == -1)
{
right[index] = data.size();
left.pb(-1);
right.pb(-1);
data.pb(0);
}
}
void push_y(int u, int d, int index)
{
if (up[index] == -1 && d - u > 1)
{
up[index] = root.size();
up.pb(-1);
down.pb(-1);
root.pb(-1);
}
if (down[index] == -1 && d - u > 1)
{
down[index] = root.size();
up.pb(-1);
down.pb(-1);
root.pb(-1);
}
if (root[index] == -1)
{
root[index] = data.size();
left.pb(-1);
right.pb(-1);
data.pb(0);
}
}
int query1d(int l, int r, int index, int ll, int rr)
{
if (index == -1 || ll >= r || l >= rr)
return 0;
if (rr >= r && l >= ll)
return data[index];
int m = l+r>>1;
int lres = query1d(l, m, left[index], ll, rr);
int rres = query1d(m, r, right[index], ll, rr);
return gcd(lres, rres);
}
int query2d(int u, int d, int index, int uu, int dd, int ll, int rr)
{
if (index == -1 || uu >= d || u >= dd)
return 0;
if (dd >= d && u >= uu)
return query1d(0, c, root[index], ll, rr);
int m = u+d>>1;
int ures = query2d(u, m, up[index], uu, dd, ll, rr);
int dres = query2d(m, d, down[index], uu, dd, ll, rr);
return gcd(ures, dres);
}
void update1d(int l, int r, int index, int x, int val)
{
if (x >= r || l > x)
return;
push_x(l, r, index);
if (l + 1 == r)
{
data[index] = val;
return;
}
int m = l+r>>1;
update1d(l, m, left[index], x, val);
update1d(m, r, right[index], x, val);
data[index] = gcd(data[left[index]], data[right[index]]);
}
void update2d(int u, int d, int index, int y, int x, int val)
{
if (y >= d || u > y)
return;
push_y(u, d, index);
if (u + 1 == d)
{
update1d(0, c, root[index], x, val);
return;
}
int m = u+d>>1;
update2d(u, m, up[index], y, x, val);
update2d(m, d, down[index], y, x, val);
}
void init(int32_t R, int32_t C)
{
r = R;
c = C;
}
void update(int32_t P, int32_t Q, int32_t K)
{
update2d(0, r, 0, P, Q, K);
}
int calculate(int32_t P, int32_t Q, int32_t U, int32_t V)
{
return query2d(0, r, 0, P, U+1, Q, V+1);
}