Submission #1350036

#TimeUsernameProblemLanguageResultExecution timeMemory
1350036Alex1298게임 (IOI13_game)C++20
0 / 100
0 ms344 KiB
#include <bits/stdc++.h>
#include "game.h"

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct Node_treap
{
    long long init;
    long long gcd;

    int key;
    int prio;
    Node_treap *left;
    Node_treap *right;

    Node_treap (int col, int x)
    {
        init = x;
        gcd = x;

        key = col;
        prio = rng();
        left = nullptr;
        right = nullptr;
    }

    void recalc()
    {
        gcd = init;
        if(left != nullptr) gcd = __gcd(gcd, left->gcd);
        if(right != nullptr) gcd = __gcd(gcd, right->gcd);
    }
};

struct Node_segtree
{
    Node_treap *treap;
    Node_segtree *left, *right;

    Node_segtree()
    {
        treap = nullptr;
        left = nullptr;
        right = nullptr;
    }
};

int n, m;
Node_segtree *root = new Node_segtree();

pair<Node_treap*, Node_treap*> split(Node_treap *treap, int x)
{
    if(treap == nullptr)
    {
        return {nullptr, nullptr};
    }

    if(treap->key <= x)
    {
        auto [left, right] = split(treap->right, x);
        treap->right = left;
        treap->recalc();

        return {treap, right};
    }
    else
    {
        auto [left, right] = split(treap->left, x);
        treap->left = right;
        treap->recalc();

        return {left, treap};
    }
}

Node_treap *merge(Node_treap *left, Node_treap *right)
{
    if(left == nullptr) return right;
    if(right == nullptr) return left;

    if(left->prio > right->prio)
    {
        left->right = merge(left->right, right);
        left->recalc();

        return left;
    }
    else
    {
        right->left = merge(left, right->left);
        right->recalc();

        return right;
    }
}

Node_treap *update_treap(Node_treap *treap, int poz, long long val)
{
    auto [left, full_right] = split(treap, poz - 1);
    auto [sub, right] = split(full_right, poz);

    if(sub != nullptr)
    {
        delete sub;
    }

    Node_treap *newNode = new Node_treap(poz, val);
    return merge(left, merge(newNode, right));
}

void update_segtree(Node_segtree *node, int left, int right, int pozx, int pozy, long long val)
{
    node->treap = update_treap(node->treap, pozy, val);

    if(left == right)
    {
        return;
    }

    int mij = (left + right) / 2;

    if(pozx <= mij)
    {
        if(node->left == nullptr)
        {
            node->left = new Node_segtree();
        }
        update_segtree(node->left, left, mij, pozx, pozy, val);
    }
    else
    {
        if(node->right == nullptr)
        {
            node->right = new Node_segtree();
        }
        update_segtree(node->right, mij+1, right, pozx, pozy, val);
    }
}

long long query_treap(Node_treap *&treap, int st, int dr)
{
    auto [left, full_right] = split(treap, st - 1);
    auto [sub, right] = split(full_right, dr);

    int ans = 0;
    if(sub != nullptr)
    {
        ans = sub->gcd;
    }

    treap = merge(left, merge(sub, right));

    return ans;
}

long long query_segtree(Node_segtree *node, int left, int right, int leftx, int rightx, int lefty, int righty)
{
    if(node == nullptr || rightx < left || right < leftx)
    {
        return 0;
    }

    if(leftx <= left && right <= rightx)
    {
        return query_treap(node->treap, lefty, righty);
    }

    int mij = (left + right) / 2;
    return __gcd(query_segtree(node->left, left, mij, leftx, rightx, lefty, righty),
                 query_segtree(node->right, mij+1, right, leftx, rightx, lefty, righty));
}

void init(int R, int C)
{
    n = R;
    m = C;
}

void update(int P, int Q, long long K)
{
    update_segtree(root, 1, n, P + 1, Q + 1, K);
}

long long calculate(int P, int Q, int U, int V)
{
    if(P > U) swap(P, U);
    if(Q > V) swap(Q, V);

    return query_segtree(root, 1, n, P + 1, Q + 1, U + 1, V + 1);
}
#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...