【codevs1191】數軸染色 並查集
阿新 • • 發佈:2019-02-01
題目描述 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
一眼線段樹,雖然能過,不過太傻X了233
每次我們摧毀了一個區間,下一次如果還要摧毀這個區間或者它的子區間的話,我們就不用處理了。這樣我們可以把每一個區間抽象成一個點,用並查集來維護。合併時將[L,R]區間全部合併,然後n–。這樣每個點只會被合併一次,複雜度
,跑得很快。
程式碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int fa[200010];
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) fa[i]=i;
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
while (find(y)!=find(x-1)) fa[find(y)]=fa[find(y)-1],n--;
printf("%d\n",n);
}
return 0;
}
/*
g++ codevs1191.cpp -o codevs1191.exe -Wall
*/