제출 #1134637

#제출 시각아이디문제언어결과실행 시간메모리
1134637byunjaewoo무지개나라 (APIO17_rainbow)C++20
35 / 100
3097 ms150160 KiB
#include "rainbow.h"
#include <bits/stdc++.h>
using namespace std;

const int N=200010, S=(1<<18);
class PST {
public:
    void init(vector<pair<int, int>> v) {
        root[0]=cnt=1;
        for(int i=1, j=0; i<N; i++) {
            bool flag=true;
            root[i]=root[i-1];
            while(j<v.size() && v[j].first==i) root[i]=update(root[i], 1, S, v[j].second), j++;
        }
    }
    int query(int sx, int sy, int ex, int ey) {
        return query(root[ex], 1, S, sy, ey)-query(root[sx-1], 1, S, sy, ey);
    }
private:
    struct Node {
        int x, l, r;
    }tree[10101010];
    int cnt, root[N];
    int update(int prev, int s, int e, int k) {
        int node=++cnt;
        tree[node].x=tree[prev].x+1, tree[node].l=tree[prev].l, tree[node].r=tree[prev].r;
        if(s==e) return node;
        int m=(s+e)/2;
        if(k<=m) tree[node].l=update(tree[prev].l, s, m, k);
        else tree[node].r=update(tree[prev].r, m+1, e, k);
        return node;
    }
    int query(int node, int s, int e, int l, int r) {
        if(!node || s>e || l>r) return 0;
        if(l<=s && e<=r) return tree[node].x;
        int m=(s+e)/2;
        return query(tree[node].l, s, m, l, r)+query(tree[node].r, m+1, e, l, r);
    }
}V, E1, E2, F;
int minr, minc, maxr, maxc;

void init(int R, int C, int sr, int sc, int M, char *S) {
    vector<pair<int, int>> v, e1, e2, f;
    v.push_back({sr, sc}), v.push_back({sr+1, sc}), v.push_back({sr, sc+1}), v.push_back({sr+1, sc+1});
    e1.push_back({sr, sc}), e1.push_back({sr, sc+1}), e2.push_back({sr, sc}), e2.push_back({sr+1, sc}), f.push_back({sr, sc});
    minr=maxr=sr, minc=maxc=sc;
    for(int i=0; i<M; i++) {
        if(S[i]=='E') sc++;
        else if(S[i]=='W') sc--;
        else if(S[i]=='N') sr--;
        else sr++;
        minr=min(minr, sr), maxr=max(maxr, sr), minc=min(minc, sc), maxc=max(maxc, sc);
        v.push_back({sr, sc}), v.push_back({sr+1, sc}), v.push_back({sr, sc+1}), v.push_back({sr+1, sc+1});
        e1.push_back({sr, sc}), e1.push_back({sr, sc+1}), e2.push_back({sr, sc}), e2.push_back({sr+1, sc}), f.push_back({sr, sc});
    }
    sort(v.begin(), v.end()), v.erase(unique(v.begin(), v.end()), v.end());
    sort(e1.begin(), e1.end()), e1.erase(unique(e1.begin(), e1.end()), e1.end());
    sort(e2.begin(), e2.end()), e2.erase(unique(e2.begin(), e2.end()), e2.end());
    sort(f.begin(), f.end()), f.erase(unique(f.begin(), f.end()), f.end());
    V.init(v), E1.init(e1), E2.init(e2), F.init(f);
}

int colour(int ar, int ac, int br, int bc) {
    int v=V.query(ar+1, ac+1, br, bc)+2*(br-ar+1+bc-ac+1);
    int e=E1.query(ar, ac+1, br, bc)+E2.query(ar+1, ac, br, bc)+2*(br-ar+1+bc-ac+1);
    int f=F.query(ar, ac, br, bc);
    int c=1+(ar<minr && maxr<br && ac<minc && maxc<bc);
    return -v+e-f+c;
}
#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...