제출 #1329580

#제출 시각아이디문제언어결과실행 시간메모리
1329580Pety게임 (IOI13_game)C++20
80 / 100
2198 ms143940 KiB
#include "game.h"
#include <iostream>


int n, m, q;

const int XMAX = 300000;
const int YMAX = 9000000;

struct Nodey {
    int l, r;
    long long gcd;
} Y[YMAX];

long long ans = 0;

struct Nodex {
    int l, r;
    int root;
} X[XMAX];

long long gcd2(long long X, long long Y) {
    long long tmp;
    while (X != Y && Y != 0) {
        tmp = X;
        X = Y;
        Y = tmp % Y;
    }
    return X;
}

void updateY (int ind, int st, int dr, int a, long long k);

long long getVal (int nod, int b) {
    long long ans = 0;
    if (nod == 0)
        return 0;
    int root = X[nod].root;
    int st = 1, dr = m;
    while (root != 0) {
        if (st == dr) {
            return Y[root].gcd;
        }
        int mid = (st + dr) / 2;
        if (mid >= b) {
            root = Y[root].l;
            dr = mid;
        }
        else {
            root = Y[root].r;
            st = mid + 1;
        }
    }
    return 0;
}

int cntX, cntY;

void updateX (int ind, int st, int dr, int a, int b, long long k) {
    if (ind == 0)
        return;
    
    Nodex &nod = X[ind];
    if (st == dr) { 
        if (nod.root == 0)
            nod.root = ++cntY;
        updateY(nod.root, 1, m, b, k);
        return;
    }
    
    int mid = (st + dr) / 2;
    if (a <= mid) {
        if (nod.l == 0)
            nod.l = ++cntX;
        updateX(nod.l, st, mid, a, b, k);
    }
    else {
        if (nod.r == 0)
            nod.r = ++cntX;
        updateX(nod.r, mid + 1, dr, a, b, k);
    }
    if (nod.root == 0)
        nod.root = ++cntY;
    updateY(nod.root, 1, m, b, gcd2(getVal(nod.l, b), getVal(nod.r, b)));
}

void updateY (int ind, int st, int dr, int a, long long k) {
    if (ind == 0)
        return;
    Nodey &nod = Y[ind];
    if (st == dr) {
        nod.gcd = k;
        return;
    }
    int mid = (st + dr) / 2;
    if (a <= mid) {
        if (nod.l == 0)
            nod.l = ++cntY;
        updateY(nod.l, st, mid, a, k);
    }
    else {
        if (nod.r == 0)
            nod.r = ++cntY;
        updateY(nod.r, mid + 1, dr, a, k);
    }
    nod.gcd = gcd2((nod.l == 0 ? 0 : Y[nod.l].gcd), (nod.r == 0 ? 0 : Y[nod.r].gcd));
}

void queryY(int ind, int st, int dr, int a, int b);

void queryX (int ind, int st, int dr, int a, int b, int c, int d) {
    if (ind == 0)
        return;
    if (b < st || a > dr)
        return;
    Nodex &nod = X[ind];
    if (a <= st && dr <= b) {
        queryY(nod.root, 1, m, c, d);
        return;
    }
    int mid = (st + dr) / 2;
    queryX(nod.l, st, mid, a, b, c, d);    
    queryX(nod.r, mid + 1, dr, a, b, c, d);    
}

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

void queryY(int ind, int st, int dr, int a, int b) {
     if (ind == 0)
        return;
    if (b < st || a > dr)
        return;
    Nodey &nod = Y[ind];
    if (a <= st && dr <= b) {
        ans = gcd2(ans, nod.gcd);
        return;
    }
    int mid = (st + dr) / 2;
    queryY(nod.l, st, mid, a, b);    
    queryY(nod.r, mid + 1, dr, a, b);    
}

void update (int p, int q, long long k) {
    p++; q++;
    updateX(1, 1, n, p, q, k);
}

long long calculate (int x1, int y1, int x2, int y2) {
    ans = 0;
    x1 ++; y1++; x2++; y2++;
    queryX(1, 1, n, x1, x2, y1, y2);
    return ans;

}
#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...