Submission #937931

#TimeUsernameProblemLanguageResultExecution timeMemory
937931Muaath_5게임 (IOI13_game)C++17
63 / 100
2610 ms256004 KiB
#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 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...