显然可以看成把有交叉的船之间连边跑二分图染色
但是边数是
O
(
n
2
)
O(n^2)
O(n2)的,考虑优化
考虑按时间轴从小到大枚举
对于当前时间如果是船
i
i
i的
B
i
B_i
Bi
即向左端点在
(
A
i
,
B
i
)
(A_i,B_i)
(Ai,Bi)且还没枚举过右端点的船连边
这样复杂度是
O
(
∣
E
∣
)
O(|E|)
O(∣E∣)的
考虑进一步优化
可以发现如果存在两个点分别向
[
a
,
b
]
,
[
c
,
d
]
[a,b],[c,d]
[a,b],[c,d]连边
且
a
<
c
<
b
<
d
a<c<b<d
a<c<b<d
那么实际上由于
[
a
,
b
]
,
[
c
,
d
]
[a,b],[c,d]
[a,b],[c,d]内都是同色的
先练了
[
a
,
b
]
[a,b]
[a,b]第二次就不需要向
[
c
,
b
)
[c,b)
[c,b)连边了
这样的话边数是
O
(
n
)
O(n)
O(n)的
可以对每个维护一个
n
x
t
nxt
nxt表示向右最大的同色的位置
从左往右用并查集维护
具体可以看代码
复杂度
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int mod=1e9+7;
inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){if(a==0&&b==0)return 0;for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
cs int N=1000005;
vector<int> e[N];
int col[N];
int nxt[N],fa[N],le[N],id[N<<1],a[N],cnt;
int n;
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void addedge(int u,int v){
e[u].pb(v),e[v].pb(u);
}
int dfs(int u){
for(int &v:e[u]){
if(col[v]!=-1&&col[v]==col[u])return 0;
if(col[v]==-1){
col[v]=col[u]^1;
if(!dfs(v))return 0;
}
}
return 1;
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read();
for(int i=1;i<=n;i++){
int l=read(),r=read();
id[l]=id[r]=i;
}
for(int i=1;i<=n;i++)nxt[i]=i,fa[i]=i;
fa[n+1]=n+1;
for(int i=1;i<=2*n;i++){
int p=id[i];
if(!le[p])a[++cnt]=p,le[p]=cnt;
else{
int u=le[p];
fa[u]=find(u+1);
for(int j=fa[u],k;j<=cnt;j=k)
addedge(a[j],p),k=find(nxt[j]+1),nxt[j]=cnt;
}
}
int cnt=0;
memset(col,-1,sizeof(col));
for(int i=1;i<=n;i++)if(col[i]==-1){col[i]=0;
if(dfs(i))cnt++;
else {puts("0");return 0;}
}
cout<<ksm(2,cnt)<<'\n';
}