正题
题目大意
给出若干个区间,然后给每个区间涂颜色(蓝或红),求一种方案使得每个点的颜色数量差不超过111。
解题思路
我们可以从每个lll向rrr连一条双向边,若此时我们可以跑出欧拉回路,那么这就满足颜色差为0(从l∼rl\sim rl∼r的涂红,r∼lr\sim lr∼l的涂蓝即可)。
但是若无法跑出欧拉回路,我们应该处理那些入度为奇数的点,我们将两两相邻配对的入度为奇数的点之间连一条边即可,我们称这个为虚边,对于虚边,是有两个边的效果抵消掉的。所以在这些边上颜色数量差为111。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510000;
struct node{int to,next,id;
}a[N*2];
int n,l[N],r[N],x[N],ls[N],tot=1,ans[N],in[N],cnt;
bool V[N],v[N];
void addl(int x,int y,int id)
{a[++tot].to=y;a[tot].next=ls[x];a[tot].id=id;ls[x]=tot;in[y]++;
}
void dfs(int x)
{V[x]=1;for(int i=ls[x];i;i=a[i].next){if(v[i]) continue;int y=a[i].to;v[i]=v[i^1]=1;dfs(y);ans[a[i].id]=(x<a[i].to);}
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&l[i],&r[i]);r[i]++;x[++cnt]=l[i];x[++cnt]=r[i];}sort(x+1,x+1+cnt);cnt=unique(x+1,x+1+cnt)-x-1;for(int i=1;i<=n;i++){l[i]=lower_bound(x+1,x+1+cnt,l[i])-x;r[i]=lower_bound(x+1,x+1+cnt,r[i])-x;addl(l[i],r[i],i);addl(r[i],l[i],i);}int last=0;for(int i=1;i<=cnt;i++)if(in[i]&1){if(last) addl(last,i,0),addl(i,last,0),last=0;else last=i;}for(int i=1;i<=cnt;i++)if(!V[i]) dfs(i);for(int i=1;i<=n;i++)printf("%d ",ans[i]);
}