Submission #1342499

#TimeUsernameProblemLanguageResultExecution timeMemory
1342499sanoGame (IOI13_game)C++20
100 / 100
3992 ms56952 KiB
#include "game.h"
#include <iostream>
#include <vector>
#include <algorithm>
#define NEK 1000000000000
#define ll long long
#define vec vector
#define For(i, n) for(int i = 0; i < n; i++)
#define pii pair<int, int>
#define ff first
#define ss second
using namespace std;
 
ll nsd(ll a, ll b){
    if(a > b) swap(a, b);
    while(a){
        b %= a;
        swap(a, b);
    }
    return b;
}

class treap{
    struct node{
        node*l = nullptr;
        node*r = nullptr;
        ll key, hod, sum;
        ll priority = rand();
        node(ll val1, ll val2){
            key = val1;
            sum = val2;
            hod = val2;
        }
    };
    typedef node* pnode;
    pnode root = nullptr;

    ll get_sum(pnode s){
        if(!s) return 0;
        return s->sum;
    }

    void update(pnode &s){
        if(!s) return;
        s->sum = nsd(nsd(get_sum(s->l), get_sum(s->r)), s->hod);
        return;
    }

    void pridaj(pnode x, pnode &t){
        if(!t) {
            t = x;
            return;
        }
        if(x->priority > t->priority){
            split(t, x->l, x->r, x->key);
            update(x);
            t = x;
            return;
        }
        x->key > t->key ? pridaj(x, t->r) : pridaj(x, t->l);
        update(t);
        return;
    }

    void erase(ll x, pnode &t){
        if(!t) return;
        if(t->key == x){
            merge(t, t->l, t->r);
            return;
        }
        x > t->key ? erase(x, t->r) : erase(x, t->l);
        update(t);
        return;
    }

    void merge(pnode &t, pnode l, pnode r){
        if(!l || !r) {
            t = l ? l : r;
            return;
        }
        if(l->priority > r->priority){
            merge(l->r, l->r, r);
            t = l;
        }
        else{
            merge(r->l, l, r->l);
            t = r;
        }
        update(t);
        return;
    }
    
    void split(pnode t, pnode &l, pnode &r, ll key){
        if(!t) {
            l = r = nullptr;
            return;
        }
        if(t->key > key){
            split(t->l, l, t->l, key);
            r = t;
        }
        else{
            split(t->r, t->r, r, key);
            l = t;
        }
        update(t);
        return;
    }

public:

    void pridaj_p(ll x, ll h){
        erase(x, root);
        pridaj(new node(x, h), root);
    }

    ll sum(ll a, ll b){
        pnode l, r;
        l = r = nullptr;
        split(root, root, r, a-1);
        split(r, l, r, b);
        ll odp = get_sum(l);
        merge(root, root, l);
        merge(root, root, r);
        return odp;
    }
};


class intervalac2d{
    ll n;
    ll m;
    struct node{
        treap in;
        node* l = nullptr;
        node* r = nullptr;
    };
    
    typedef node* pnode;
    pnode root = nullptr;

    ll get_range(pnode s, ll a, ll b){
        if(!s) return (ll)0;
        return s->in.sum(a, b);
    }

    void zmen(ll a, ll b, ll x, ll l, ll r, pnode& s){
        if(a < l || a > r) return;
        if(!s) s = new node;
        if(l == r){
            s->in.pridaj_p(b, x);
            return;
        }
        ll mid = (l+r)/2;
        zmen(a, b, x, l, mid, s->l); zmen(a, b, x, mid+1, r, s->r);
        ll val = nsd(get_range(s->l, b, b), get_range(s->r, b, b));
        s->in.pridaj_p(b, val);
        return;
    }

    ll daj(ll a, ll b, ll c, ll d, ll l, ll r, pnode&s){
        if(a > r || b < l) return (ll)0;
        if(!s) return (ll)0;
        if(a <= l && r <= b) {
            return s->in.sum(c, d);
        }
        ll mid = (l+r)/2;
        return nsd(daj(a, b, c, d, l, mid, s->l), daj(a, b, c, d, mid+1, r, s->r));
    }

public:
    void postav(ll v1, ll v2){
        n = v1, m = v2;
    }
    void zmen_p(ll a, ll b, ll x){
        zmen(a, b, x, 0, n-1, root);
    }
    ll daj_p(ll a, ll b, ll c, ll d){
        return daj(a, b, c, d, 0, n-1, root);
    }
};

intervalac2d seg;


void init(int r1, int c1){
    ll r = r1, c = c1;
    seg.postav(r, c);
    return;
}

void update(int a1, int b1, ll k){
    ll a = a1, b = b1;
    seg.zmen_p(a, b, k);
    return;
}

ll calculate(int a1, int b1, int c1, int d1){
    ll a = a1, b = b1, c = c1, d = d1;
    return seg.daj_p(min(a, c), max(a, c), min(b, d), max(b, d));
}
#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...