Submission #232960

#TimeUsernameProblemLanguageResultExecution timeMemory
232960thebesPort Facility (JOI17_port_facility)C++14
100 / 100
3951 ms682188 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef vector<int> vi;
#define F first
#define S second
#define pb push_back

const int MN = 1e6+6, mod = 1e9+7;
int N, i, j, x, y, vs[MN], on[MN], col[MN], cur, ans=1;
pii arr[MN], evt[2*MN]; stack<int> stk[2]; queue<int> go;

struct SegmentTree{ // range update, point query
    pii *st[6*MN];
    int sz[6*MN], n;
    inline void init(int N){
        n = N;
    }
    void pre(int i,int s,int e,int ss,int se){
        if(s>=ss&&e<=se) sz[i]++;
        else if((s+e)/2<ss) pre(2*i+1,(s+e)/2+1,e,ss,se);
        else if((s+e)/2>=se) pre(2*i,s,(s+e)/2,ss,se);
        else pre(2*i,s,(s+e)/2,ss,se), pre(2*i+1,(s+e)/2+1,e,ss,se);
    }
    inline void pre(int s,int e){
        pre(1,1,n,s,e);
    }
    void build(int i,int s,int e){
        if(s!=e){
            build(2*i,s,(s+e)/2);
            build(2*i+1,(s+e)/2+1,e);
        }
        st[i]=(pii*)malloc(sz[i]*sizeof(pii));
        sz[i]=-1;
    }
    inline void build(){
        build(1,1,n);
    }
    void upd(int i,int s,int e,int ss,int se,int id,int y){
        if(s>=ss&&e<=se) st[i][++sz[i]]={y,id};
        else if((s+e)/2<ss) upd(2*i+1,(s+e)/2+1,e,ss,se,id,y);
        else if((s+e)/2>=se) upd(2*i,s,(s+e)/2,ss,se,id,y);
        else upd(2*i,s,(s+e)/2,ss,se,id,y), upd(2*i+1,(s+e)/2+1,e,ss,se,id,y);
    }
    inline void upd(int s,int e,int id,int y){
        upd(1,1,n,s,e,id,y);
    }
    void qu(int i,int s,int e,int idx,int y){
        while(sz[i]>=0&&st[i][sz[i]].F<=y){
            if(!vs[st[i][sz[i]].S]){
                vs[st[i][sz[i]].S]=1;
                col[st[i][sz[i]].S]=!col[cur];
                go.push(st[i][sz[i]].S);
            }
            sz[i]--;
        }
        if(s!=e){
            if((s+e)/2<idx) qu(2*i+1,(s+e)/2+1,e,idx,y);
            else qu(2*i,s,(s+e)/2,idx,y);
        }
    }
    inline void qu(int idx,int y){
        qu(1,1,n,idx,y);
    }
}st;

struct SegmentTree2{ // point update, range query
    pii *st[6*MN];
    int sz[6*MN], n;
    inline void init(int N){
        n = N;
    }
    void pre(int i,int s,int e,int idx){
        sz[i]++;
        if(s!=e){
            if((s+e)/2<idx) pre(2*i+1,(s+e)/2+1,e,idx);
            else pre(2*i,s,(s+e)/2,idx);
        }
    }
    inline void pre(int idx){
        pre(1,1,n,idx);
    }
    void build(int i,int s,int e){
        st[i]=(pii*)malloc(sz[i]*sizeof(pii));
        sz[i]=-1;
        if(s!=e){
            build(2*i,s,(s+e)/2);
            build(2*i+1,(s+e)/2+1,e);
        }
    }
    inline void build(){
        build(1,1,n);
    }
    void upd(int i,int s,int e,int idx,int id,int y){
        st[i][++sz[i]]={y,id};
        if(s!=e){
            if((s+e)/2<idx) upd(2*i+1,(s+e)/2+1,e,idx,id,y);
            else upd(2*i,s,(s+e)/2,idx,id,y);
        }
    }
    inline void upd(int idx,int id,int y){
        upd(1,1,n,idx,id,y);
    }
    void qu(int i,int s,int e,int ss,int se,int y){
        if(s>=ss&&e<=se){
            while(sz[i]>=0&&st[i][sz[i]].F>=y){
                if(!vs[st[i][sz[i]].S]){
                    vs[st[i][sz[i]].S]=1;
                    col[st[i][sz[i]].S]=!col[cur];
                    go.push(st[i][sz[i]].S);
                }
                sz[i]--;
            }
        }
        else if((s+e)/2<ss) qu(2*i+1,(s+e)/2+1,e,ss,se,y);
        else if((s+e)/2>=se) qu(2*i,s,(s+e)/2,ss,se,y);
        else qu(2*i,s,(s+e)/2,ss,se,y), qu(2*i+1,(s+e)/2+1,e,ss,se,y);
    }
    inline void qu(int s,int e,int y){
        qu(1,1,n,s,e,y);
    }
}st2;

int main(){
    scanf("%d",&N);
    st.init(2*N), st2.init(2*N);
    for(i=1;i<=N;i++)
        scanf("%d%d",&arr[i].F,&arr[i].S);
    sort(arr+1,arr+N+1,[](pii i,pii j){return i.S<j.S;});
    for(i=N;i>=1;i--)
        st.pre(arr[i].F,arr[i].S);
    for(i=1;i<=N;i++)
        st2.pre(arr[i].F);
    st.build(), st2.build();
    for(i=N;i>=1;i--)
        st.upd(arr[i].F,arr[i].S,i,arr[i].S);
    for(i=1;i<=N;i++)
        st2.upd(arr[i].F,i,arr[i].S);
    for(i=1;i<=N;i++){
        if(!vs[i]){
            ans = 2LL*ans%mod;
            vs[i] = 1;
            go.push(i);
            while(go.size()){
                cur=go.front(); go.pop();
                st.qu(arr[cur].F,arr[cur].S);
                st2.qu(arr[cur].F,arr[cur].S,arr[cur].S);
            }
        }
    }
    for(i=1;i<=N;i++){
        evt[2*i-1]={arr[i].F, i};
        evt[2*i]={arr[i].S, i};
    }
    sort(evt+1,evt+2*N+1,[](pii i,pii j){return i.F<j.F;});
    for(i=1;i<=2*N;i++){
        cur = evt[i].S;
        if(on[cur]){
            if(stk[col[cur]].empty()||stk[col[cur]].top()!=cur){
                ans = 0;
                break;
            }
            stk[col[cur]].pop();
        }
        else stk[col[cur]].push(cur);
        on[cur]=!on[cur];
    }
    printf("%d\n",ans);
    return 0;
}

Compilation message (stderr)

port_facility.cpp: In function 'int main()':
port_facility.cpp:128:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d",&N);
     ~~~~~^~~~~~~~~
port_facility.cpp:131:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d",&arr[i].F,&arr[i].S);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...