CF429E Points and Segments 题解
思路
首先这里有一个结论是一定不会有无解的情况。
发现这种形如“绝对值不超过1”的描述,考虑建图以后跑欧拉回路去确定边的方向来确定颜色。
现在来考虑如何建模。
一个发现是被覆盖次数为偶数的点一定可以通过调整来达到合法。因此我们考虑将被覆盖次数为奇数的点统计出来。当然这些点可能会很多。但是连续的奇数点是可以被合并的,因此直接离散化一下即可。
然后我们将所有给定的区间和被覆盖次数为奇数次的点拉出来建图。由于我们是覆盖问题,因此我们令连的边的区间是左闭右开的。
然后对于每个区间 \([l,r]\) 让 \(l\) 与 \(r\) 连边;对于每个被覆盖次数为奇数次的点,我们令 \(i\) 向 \(i+1\) 连边即可。
code
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+7;
int n,hd[N],nxt[N],to[N],l[N],r[N],cnt=0,tmp[N],d[N],idcnt=-1,vis[N],ans[N];
void add(int u,int v){nxt[++idcnt]=hd[u];to[idcnt]=v;hd[u]=idcnt;}
void dfs(int u){
vis[u]=1;
for(int &i=hd[u];i!=-1;i=nxt[i]){
if(ans[i]==-1){
ans[i]=ans[i^1]=(i&1);dfs(to[i]);
}
}
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;for(int i=1;i<=n;i++){cin>>l[i]>>r[i];r[i]++;tmp[++cnt]=l[i],tmp[++cnt]=r[i];}
sort(tmp+1,tmp+cnt+1);cnt=unique(tmp+1,tmp+cnt+1)-(tmp+1);
for(int i=1;i<=cnt;i++) hd[i]=-1;
for(int i=1;i<=n;i++){
l[i]=lower_bound(tmp+1,tmp+cnt+1,l[i])-tmp;r[i]=lower_bound(tmp+1,tmp+cnt+1,r[i])-tmp;
add(l[i],r[i]),add(r[i],l[i]);d[l[i]]++,d[r[i]]--;//这个东西是在判断奇数的区间
}
for(int i=1;i<=cnt;i++){d[i]+=d[i-1];if(d[i]&1) add(i,i+1),add(i+1,i);}
for(int i=0;i<=idcnt;i++) ans[i]=-1;
for(int i=1;i<=cnt;i++) if(!vis[i])dfs(i);
for(int i=1;i<=n;i++) cout<<ans[(i-1)*2]<<' ';
return 0;
}

浙公网安备 33010602011771号