Restructuring Company (並查集的區間合併)
阿新 • • 發佈:2019-01-22
題目大意:
一共有n個單點集,三種操作:
type1 x y代表:合併x和y所在集合
type2 x y代表 :合併x,x+1,…,y-1,y(x到y的區間)所在集合
type3 x y代表 :查詢x和y是否在同一集合 是 輸出YES, 否 輸出NO
思路:暴力合併會超時,需要加個優化,nex陣列表示:不屬於這個集合的第一個編號,把nex陣列初始化為nex[i]=i+1,區間合併的時候,把區間[x,y]中所有點的nex[i]值全部更新為nex[y]的值,下次再合併到這個區間,就可以直接跳過這段, 省了好多時間
AC程式碼
#include<bits/stdc++.h> using namespace std; int n, q; int p[200005], nex[200005]; ///nex陣列記錄第一個不屬於這個集合的數 int mergee(int x) { if(p[x] != x) p[x] = mergee(p[x]); return p[x]; } int main() { while(scanf("%d%d", &n, &q)!=EOF) { for(int i = 1; i <= n; i++) p[i] = i, nex[i] = i+1; while(q--) { int a, x, y, to; scanf("%d%d%d", &a, &x, &y); if(a == 1) p[mergee(y)] = mergee(x); else if(a == 2) { for(int i = x+1; i <= y; i = to) { p[mergee(i)] = mergee(i-1); to = nex[i]; nex[i] = nex[y]; } } else { if(mergee(x)!=mergee(y))printf("NO\n"); else printf("YES\n"); } } } return 0; }