Submission #756471

#TimeUsernameProblemLanguageResultExecution timeMemory
756471Muaath_5Game (IOI13_game)C++17
63 / 100
2487 ms250632 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'313'505'509;
    const int SZ = 4'500'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...