Submission #1080139

#TimeUsernameProblemLanguageResultExecution timeMemory
1080139isaachewPort Facility (JOI17_port_facility)C++17
100 / 100
983 ms271204 KiB
#include <bits/stdc++.h> /* Two stacks Ranges intersect -> not on the same stack Segtree and DSU Very similar to BOJ 7083 */ bool possible; int numccs; std::vector<int> parents; std::vector<int> states; int find(int x){//parent, its state if(parents[x]==-1)return x; int fnd=find(parents[x]); if(fnd!=parents[x]){//fnd is the parent's parent states[x]^=states[parents[x]]; parents[x]=fnd; } return fnd; } bool merge(int a,int b){//merging with opposite parity; returns false if cannot int fa=find(a); int fb=find(b); if(fa==fb){ return states[a]!=states[b]; } numccs--; states[fb]=states[b]^states[a]^1; parents[fb]=fa; return 1; } struct segtree{ int size; std::vector<std::vector<int>> nodes;//it is cleared every time anyway segtree(int n){ nodes.resize(2*n-1); size=n; } void add(int l,int r,int x,int nl,int nr,int ni){ if(r<=nl||l>=nr)return; if(l<=nl&&r>=nr){ nodes[ni].push_back(x); return; } int nm=(nl+nr)/2; add(l,r,x,nl,nm,ni+1); add(l,r,x,nm,nr,ni+2*(nm-nl)); } void query(int pos,int val,int nl,int nr,int ni){ if(pos<nl||pos>=nr)return; for(int i:nodes[ni]){ possible&=merge(i,val); } if(nodes[ni].size()>1)nodes[ni].resize(1);//max looked at is 1 as everything was merged if(nl+1>=nr)return; int nm=(nl+nr)/2; query(pos,val,nl,nm,ni+1); query(pos,val,nm,nr,ni+2*(nm-nl)); } }; int main(){ std::ios::sync_with_stdio(0); std::cin.tie(0); int m; std::cin>>m; int n=2*m; numccs=m; std::vector<std::pair<int,int>> intervs; std::vector<int> sinds; for(int i=0;i<m;i++){ sinds.push_back(i); int a,b; std::cin>>a>>b; a--,b--; intervs.push_back({std::min(a,b),std::max(a,b)}); } std::sort(sinds.begin(),sinds.end(),[&](int a,int b){return intervs[a].second<intervs[b].second;}); parents.resize(m,-1); states.resize(m,0); segtree st(n); possible=true; for(int i=0;i<m;i++){ st.query(intervs[sinds[i]].first,i,0,n,0); st.add(intervs[sinds[i]].first,intervs[sinds[i]].second,i,0,n,0); if(!possible)break; } long long curnum=1; long long squ=2; for(int i=numccs;i;){ if(i&1){ curnum*=squ; curnum%=1000000007; } squ*=squ; squ%=1000000007; i/=2; } std::cout<<(possible?curnum:0)<<'\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...