【noi.ac #1779】D

題目

在一個數軸上一共有 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,數據保證至少有一組解。

思路

我們把黑的看成 +1+1,白的看成 1-1。對於區間 [l,r][l,r],做個差分,便可以看做是一條從 llr+1r+1 的邊。

我們想要的是每個位置是 0,±10, \pm 1,這個對應到差分上值有 0,±1,±20, \pm 1, \pm 2,不太好處理。但是如果我們想要的是每個位置都是 00,那麼差分後每個位置都是 00,也就是說如果建出來的圖存在歐拉回路,那麼我們按照歐拉回路上的邊的方向就可以得到一組解。

對於原題,可以發現爲 ±1\pm 1 的一定是被覆蓋奇數次的位置,那麼新增一些區間來覆蓋它們,使得每個位置都爲偶數次。這個時候建出來的圖也一定是存在歐拉回路的,於是我們就得到了一組滿足每個位置都是 0,±10, \pm 1 的解。

代碼

#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]);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章