Restructuring Company (并查集的区间合并)

题目链接https://cn.vjudge.net/problem/CodeForces-566D

题目大意:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值