題目
在一個數軸上一共有 NN 段閉區間,它們可能有交。
現在你需要對它們黑白染色。對於每個位置 xx ,假設覆蓋它的黑色區間個數爲 bxbx,覆蓋它的白色區間個數爲 wxwx,要求滿足 |bx−wx|≤1|bx−wx|≤1。區間 [l,r][l,r] 覆蓋位置 xx 當且僅當 l≤x≤rl≤x≤r。
給出任意一種方案即可。
輸入格式
第一行兩個整數 NN。
接下來 NN 行,每行兩個整數 li,rili,ri,表示一個 [li,ri][li,ri] 的區間。
輸出格式
一共 NN 個 0/10/1 數,其中第 ii 個數爲 11 表示第 ii 個區間染黑,否則爲染黑。
樣例一
Input
2
1 3
3 5
Output
1 0
樣例二
Input
5
1 5
3 9
4 8
5 9
6 8
Output
1 0 0 1 1
數據範圍
30%的數據滿足:N≤20N≤20
60%的數據滿足:N≤500N≤500
對於100%的數據滿足:N≤105,0≤li≤ri≤109N≤105,0≤li≤ri≤109,數據保證至少有一組解。
思路
我們把黑的看成 ,白的看成 。對於區間 ,做個差分,便可以看做是一條從 到 的邊。
我們想要的是每個位置是 ,這個對應到差分上值有 ,不太好處理。但是如果我們想要的是每個位置都是 ,那麼差分後每個位置都是 ,也就是說如果建出來的圖存在歐拉回路,那麼我們按照歐拉回路上的邊的方向就可以得到一組解。
對於原題,可以發現爲 的一定是被覆蓋奇數次的位置,那麼新增一些區間來覆蓋它們,使得每個位置都爲偶數次。這個時候建出來的圖也一定是存在歐拉回路的,於是我們就得到了一組滿足每個位置都是 的解。
代碼
#include<bits/stdc++.h>
#define register
using namespace std;
const int N=2e5+77;
int fa[N],vl[N];
int gf(int a)
{
if(a==fa[a])return a;
int x=gf(fa[a]);
vl[a]^=vl[fa[a]];fa[a]=x;
return x;
}
pair<int,int>pp[N];
int main()
{
int n,l,r;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&l,&r);
pp[i*2-1]=std::make_pair(l,i);
pp[i*2]=std::make_pair(r,i+n);
fa[i]=fa[i+n]=i,vl[i+n]=1;
}
sort(pp+1,pp+2*n+1);
int nw=0;
for(int i=1;i<=2*n;i++)
{
int no=pp[i].second;
if(!nw)nw=no;
else
{
if(gf(nw)!=gf(no))
{
vl[fa[no]]=vl[no]^vl[nw]^1;
fa[fa[no]]=fa[nw];
}
nw=0;
}
}
for(int i=1;i<=n;i++)
{
gf(i);
printf("%d ",vl[i]);
}
}