제출 #1356626

#제출 시각아이디문제언어결과실행 시간메모리
1356626AvianshTiles (BOI24_tiles)C++20
0 / 100
511 ms1067704 KiB
#include <bits/stdc++.h>

using namespace std;

struct segTree{
    struct node{
        ///vertical range:
        int len;
        int prefoddcnt, sufoddcnt; ///stores current active count
        int prefevcnt, sufevcnt; ///stores current active count
        bool oddrang; ///stores if odd rang has been discovered
        ///horizontal range:
        bool oddtim; ///stores if odd start x exists.
        bool evtim; ///stores if even start x exists.
        ///lazy:
        bool lazodd; ///stores if range was changed to this
        bool lazev; ///stores if range was changed to this
        bool delted; ///stores if has been deleted
        ///no need to store for vertical since length is predetermined
        ///if lazodd||lazev, range was updated to be active
        ///must ensure both lazev and lazodd are not one at same time in push
        ///childs:
        int l,r;
    };
    node unite(node a, node b){
        node ans;
        ans=def;
        ans.len=a.len+b.len;
        ans.prefoddcnt = a.prefoddcnt + (a.prefoddcnt==a.len ? b.prefoddcnt : 0);
        ans.prefevcnt = a.prefevcnt + (a.prefevcnt==a.len ? b.prefevcnt : 0);
        ans.sufoddcnt = b.sufoddcnt + (b.sufoddcnt == b.len ? a.sufoddcnt : 0);
        ans.sufevcnt = b.sufevcnt + (b.sufevcnt == b.len ? a.sufevcnt : 0);
        ans.oddrang = a.oddrang||b.oddrang||(((a.sufoddcnt+b.prefoddcnt)%2)&&(a.sufoddcnt!=a.len)&&(b.prefoddcnt!=b.len))||(((a.sufevcnt+b.prefevcnt)%2)&&(a.sufevcnt!=a.len)&&(b.prefevcnt!=b.len));
        ans.oddtim=a.oddtim||b.oddtim;
        ans.evtim=a.evtim||b.evtim;
        assert(!(a.lazodd||b.lazodd||a.lazev||b.lazev||a.delted||b.delted));
        return ans;
    }
    int cr = 0;
    void makeKids(int l, int r, int ind){
        if(l==r)
            return;
        if(st[ind].l!=-1)
            return;
        int mid = (l+r)/2;
        st[ind].l=++cr;
        st[st[ind].l].len=(mid-l+1);
        st[ind].r=++cr;
        st[st[ind].r].len=(r-mid);
    }
    void push(int l, int r, int ind){
        makeKids(l,r,ind);
        if(st[ind].lazodd||st[ind].lazev){
            ///this was activated
            assert(!st[ind].delted);
            assert(st[ind].lazodd^st[ind].lazev);
            if(st[ind].lazodd){
                st[ind].evtim=0;
                st[ind].oddtim=1;
                st[ind].prefoddcnt=st[ind].len;
                st[ind].prefevcnt=0;
                st[ind].sufoddcnt=st[ind].len;
                st[ind].sufevcnt=0;
                st[ind].oddrang=0;
                if(l<r){
                    st[st[ind].l].lazodd=1;
                    st[st[ind].l].lazev=0;
                    st[st[ind].l].delted=0;
                    st[st[ind].r].lazodd=1;
                    st[st[ind].r].lazev=0;
                    st[st[ind].r].delted=0;
                }
                st[ind].lazodd=0;
            }
            else{
                st[ind].evtim=1;
                st[ind].oddtim=0;
                st[ind].prefoddcnt=0;
                st[ind].prefevcnt=st[ind].len;
                st[ind].sufoddcnt=0;
                st[ind].sufevcnt=st[ind].len;
                st[ind].oddrang=0;
                if(l<r){
                    st[st[ind].l].lazodd=0;
                    st[st[ind].l].lazev=1;
                    st[st[ind].l].delted=0;
                    st[st[ind].r].lazodd=0;
                    st[st[ind].r].lazev=1;
                    st[st[ind].r].delted=0;
                }
                st[ind].lazev=0;
            }
        }
        else if(st[ind].delted){
            ///was deleted pass on
            int lef = st[ind].l;
            int rig = st[ind].r;
            st[ind]=def;
            st[ind].l=lef;
            st[ind].r=rig;
            st[ind].len=r-l+1;
            if(l<r){
                st[st[ind].l].delted=1;
                st[st[ind].l].lazodd=st[st[ind].l].lazev=0;
                st[st[ind].r].delted=1;
                st[st[ind].r].lazodd=st[st[ind].r].lazev=0;
            }
            st[ind].delted=0;
        }
    }
    node *st;
    node def;
    segTree(int nodes){
        st=new node[nodes];
        def.prefoddcnt=0;
        def.prefevcnt=0;
        def.len=0;
        def.sufoddcnt=0;
        def.sufevcnt=0;
        def.oddrang=0;
        def.oddtim=0;
        def.evtim=0;
        def.lazodd=0;
        def.lazev=0;
        def.delted=0;
        def.l=-1;
        def.r=-1;
        fill(st,st+nodes,def);
    }
    void flip(int l, int r, int s, int e, int ind, int tim){
        push(l,r,ind);
        if(e<l||s>r){
            return;
        }
        if(s<=l&&r<=e){
            ///figure out if exists or no
            if(st[ind].oddtim||st[ind].evtim){
                ///it has been removed
                st[ind].delted=1;
                push(l,r,ind);
            }
            else{
                ///has come into existance
                if(tim%2){
                    st[ind].lazodd=1;
                }
                else{
                    st[ind].lazev=1;
                }
                push(l,r,ind);
            }
            return;
        }
        int mid = (l+r)/2;
        flip(l,mid,s,e,st[ind].l,tim);
        flip(mid+1,r,s,e,st[ind].r,tim);
        int lef = st[ind].l;
        int rig = st[ind].r;
        st[ind]=unite(st[st[ind].l],st[st[ind].r]);
        st[ind].l=lef;
        st[ind].r=rig;
    }
    node query(int l, int r, int s, int e, int ind){
        push(l,r,ind);
        if(e<l||s>r){
            return def;
        }
        if(s<=l&&r<=e){
            return st[ind];
        }
        int mid = (l+r)/2;
        node ans = unite(query(l,mid,s,e,st[ind].l),query(mid+1,r,s,e,st[ind].r));
        return ans;
    }
};

const int mxy = 1e9+5;

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,m;
    cin >> n >> m;
    int lasx,lasy;
    cin >> lasx >> lasy;
    int firx = lasx;
    int firy = lasy;
    lasy++;
    map<int,vector<array<int,2>>>mp;
    for(int i = 1;i<n;i++){
        int x,y;
        cin >> x >> y;
        y++;
        if(x==lasx){
            mp[x].push_back({min(lasy,y),max(lasy,y)});
        }
        lasx=x;
        lasy=y;
    }
    firy++;
    if(firx==lasx){
        mp[firx].push_back({min(lasy,firy),max(lasy,firy)});
    }
    ///sorted evs on x
    segTree st(3e7);
    int ans = 0;
    for(pair<int,vector<array<int,2>>>p:mp){
        int x = p.first;
        ///check this x
        if((st.st[0].oddtim&&(x%2==0))||((st.st[0].evtim&&(x%2==1)))){
            ///bad
        }
        else{
            ///x is possible
            ans=max(ans,x);
        }
        ///check x-1
        if(x){
            x--;
            if((st.st[0].oddtim&&(x%2==0))||((st.st[0].evtim&&(x%2==1)))){
                ///bad
            }
            else{
                ///x is possible
                ans=max(ans,x);
            }
            x++;
        }

        ///do updates on x
        bool val = 1;
        for(array<int,2>upd : p.second){
            upd[1]--;
            segTree::node cur = st.query(0,mxy,upd[0],upd[1],0);
            if((cur.oddtim&&(x%2==0))||(cur.evtim&&(x%2==1))){
                val=0;
                break;
            }
            st.flip(0,mxy,upd[0],upd[1],0,x);
        }
        if((!val)||st.st[0].oddrang)
            break;
    }
    cout << ans;
    return 0;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...