1. 程式人生 > >Restructuring Company (並查集的區間合併)

Restructuring Company (並查集的區間合併)

題目大意:

一共有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;
}