제출 #1351756

#제출 시각아이디문제언어결과실행 시간메모리
1351756AvianshLand of the Rainbow Gold (APIO17_rainbow)C++20
0 / 100
372 ms538912 KiB
#include <bits/stdc++.h>
#include "rainbow.h"

using namespace std;

const int mxn=2e5+5;

///persistent sum segtree
struct segTree{
    set<int>pts[mxn];
    int roots[mxn];
    struct node{
        int sum,l,r;
    };
    node *st;
    node def;
    int cr = 1;
    segTree(int nodes){
        st=new node[nodes];
        def.sum=0;
        def.l=0;
        def.r=0;
        fill(st,st+nodes,def);
        roots[0]=1;
    }

    void build(){
        for(int i = 1;i<mxn;i++){
            roots[i]=cpy(roots[i-1]);
            for(int y : pts[i]){
                update(0,mxn,y,1,roots[i]);
            }
        }
    }

    void add(int x, int y){
        pts[x].insert(y);
    }

    int cpy(int ind){
        st[++cr]=st[ind];
        return cr;
    }

    void update(int l, int r, int i, int val, int ind){
        if(l==r){
            st[ind].sum+=val;
            return;
        }
        int mid = (l+r)/2;
        if(i<=mid){
            st[ind].l=cpy(st[ind].l);
            update(l,mid,i,val,st[ind].l);
        }
        else{
            st[ind].r=cpy(st[ind].r);
            update(mid+1,r,i,val,st[ind].r);
        }
        st[ind].sum=st[st[ind].l].sum+st[st[ind].r].sum;
    }
    int query(int l, int r, int s, int e, int ind){
        if(st[ind].sum==0){
            return 0;
        }
        if(e<l||s>r)
            return 0;
        if(s<=l&&r<=e){
            return st[ind].sum;
        }
        int mid = (l+r)/2;
        return query(l,mid,s,e,st[ind].l)+query(mid+1,r,s,e,st[ind].r);
    }
};

const int nodes = 1e7;
segTree verts(nodes), rivers(nodes), edges_horizontal(nodes), edges_vertical(nodes);
void add_river(int x, int y){
    ///add vertices
    verts.add(x,y);
    verts.add(x+1,y);
    verts.add(x,y+1);
    verts.add(x+1,y+1);

    rivers.add(x,y);

    edges_horizontal.add(x,y);
    edges_horizontal.add(x+1,y);

    edges_vertical.add(x,y);
    edges_vertical.add(x,y+1);
}

void init(int R, int C, int sr, int sc, int M, char *S) {
    add_river(sr,sc);
    for(int i = 0;i<M;i++){
        if(S[i]=='N'){
            sr--;
        }
        if(S[i]=='S'){
            sr++;
        }
        if(S[i]=='W'){
            sc--;
        }
        if(S[i]=='E'){
            sc++;
        }
        add_river(sr,sc);
    }
    verts.build();
    rivers.build();
    edges_horizontal.build();
    edges_vertical.build();
}

int colour(int ar, int ac, int br, int bc) {
    int l = (br-ar+1);
    int b = (bc-ac+1);
    int R = 2*(l+b+2) + rivers.query(0,mxn,ac,bc,rivers.roots[br]) - rivers.query(0,mxn,ac,bc,rivers.roots[ar-1]);
    int V = 4*(l+b+2) + verts.query(0,mxn,ac+1,bc,verts.roots[br]) - verts.query(0,mxn,ac+1,bc,verts.roots[ar]);
    int E = edges_horizontal.query(0,mxn,ac,bc,edges_horizontal.roots[br]) - edges_horizontal.query(0,mxn,ac,bc,edges_horizontal.roots[ar]);
    E+=edges_vertical.query(0,mxn,ac+1,bc,edges_vertical.roots[br]) - edges_vertical.query(0,mxn,ac+1,bc,edges_vertical.roots[ar-1]);
    E+=4*l+4*b+8+8+2*(b-1)+2*(l-1);
    int C = (((rivers.query(0,mxn,ac,ac,rivers.roots[br]) - rivers.query(0,mxn,ac,ac,rivers.roots[ar-1]))||(rivers.query(0,mxn,bc,bc,rivers.roots[br]) - rivers.query(0,mxn,bc,bc,rivers.roots[ar-1]))||(rivers.query(0,mxn,ac,bc,rivers.roots[br]) - rivers.query(0,mxn,ac,bc,rivers.roots[br-1]))||(rivers.query(0,mxn,ac,bc,rivers.roots[ar]) - rivers.query(0,mxn,ac,bc,rivers.roots[ar-1])))&&(R-2*(l+b+2))) ? 1 : 2;
    return E-V+C-R;
}

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