Submission #739596

#TimeUsernameProblemLanguageResultExecution timeMemory
739596Muaath_5Game (IOI13_game)C++17
63 / 100
2187 ms256000 KiB
//#pragma GCC optimize("Ofast,avx2")
#include "game.h"
#include <numeric>
#define ll long long
#define OUT 0
#define merge gcd
using namespace std;

const int N = (1<<30);

struct ynode {
    ynode() : val(OUT), left(nullptr), right(nullptr) {}
    ll val = OUT;
    ynode *left, *right;
};

struct xnode {
    xnode() : left(nullptr), right(nullptr), yy(ynode()) {}
    xnode *left, *right;
    ynode yy;
} *root;

ll query_y(const int &qy1, const int &qy2, const ynode* node, int l = 0, int r = N - 1)
{
    if (node == nullptr || r < qy1 || qy2 < l) return OUT;
    if (qy1 <= l && r <= qy2) return node->val;
    const int mid = (l + r) / 2;
    return merge(
        query_y(qy1, qy2, node->left, l, mid),
        query_y(qy1, qy2, node->right, mid + 1, r)
    );
}

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 (node == nullptr || r < qx1 || qx2 < l) return OUT;
    if (qx1 <= l && r <= qx2) return query_y(qy1, qy2, &node->yy);
    const int mid = (l + r) / 2;
    return merge(
        query_x(qx1, qy1, qx2, qy2, node->left, l, mid),
        query_x(qx1, qy1, qx2, qy2, node->right, mid + 1, r)
    );
}


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 = new ynode();
        update_y(qy, val, node->left, l, mid);
    }
    else {
        if (!node->right) node->right = new ynode();
        update_y(qy, val, node->right, mid + 1, r);
    }
    node->val = merge((node->left ? node->left->val : OUT), (node->right ? 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 (l == r) {
        update_y(qy, val, &node->yy);
        return;
    }
    const int mid = (l + r) / 2;
    if (qx <= mid) {
        if (!node->left) node->left = new xnode();
        update_x(qx, qy, val, node->left, l, mid);
    }
    else {
        if (!node->right) node->right = new xnode();
        update_x(qx, qy, val, node->right, mid + 1, r);
    }
    update_y(qy, merge(
        (node->left ? query_y(qy, qy, &node->left->yy) : OUT),
        (node->right ? query_y(qy, qy, &node->right->yy) : OUT)
    ), &node->yy);
}

void init(int R, int C) { root = new 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...