1. 程式人生 > >codevs 1191 數軸染色

codevs 1191 數軸染色

pull tab 100% -s wrap inpu div btn -1

1191 數軸染色

時間限制: 1 s 空間限制: 128000 KB 題目等級 : 黃金 Gold 題目描述 Description

在一條數軸上有N個點,分別是1~N。一開始所有的點都被染成黑色。接著
我們進行M次操作,第i次操作將[Li,Ri]這些點染成白色。請輸出每個操作執行後
剩余黑色點的個數。

輸入描述 Input Description

輸入一行為N和M。下面M行每行兩個數Li、Ri

輸出描述 Output Description

輸出M行,為每次操作後剩余黑色點的個數。

樣例輸入 Sample Input

10 3
3 3
5 7
2 8

樣例輸出 Sample Output

9
6
3

數據範圍及提示 Data Size & Hint

數據限制
對30%的數據有1<=N<=2000,1<=M<=2000
對100%數據有1<=Li<=Ri<=N<=200000,1<=M<=200000

看了別人的的題解,發現能用並查集!好神吶,以下為原話

每次我們摧毀了一個區間,下一次如果還要摧毀這個區間或者它的子區間的話,我們就不用處理了。這樣我們可以把每一個區間抽象成一個點,用並查集來維護。合並時將[L,R]區間全部合並,然後n–。這樣每個點只會被合並一次
#include<cstdio>

int
father[200010]; int find(int x) { if(father[x]!=x)father[x]=find(father[x]); return father[x]; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<=n;i++) father[i]=i; for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y);
while(find(y)!=find(x-1)) { father[find(y)]=father[find(y)-1]; n--; } printf("%d\n",n); } return 0; }

codevs 1191 數軸染色