Restructuring Company(并查集+区间合并优化)

Even the most successful company can go through a crisis period when you have to make a hard decision — to restructure, discard and merge departments, fire employees and do other unpleasant stuff. Let’s consider the following model of a company.
There are n people working for the Large Software Company. Each person belongs to some department. Initially, each person works on his own project in his own department (thus, each company initially consists of n departments, one person in each).
However, harsh times have come to the company and the management had to hire a crisis manager who would rebuild the working process in order to boost efficiency. Let’s use team(person) to represent a team where person person works. A crisis manager can make decisions of two types:
Merge departments team(x) and team(y) into one large department containing all the employees of team(x) and team(y), where x and y (1 ≤ x, y ≤ n) — are numbers of two of some company employees. If team(x) matches team(y), then nothing happens.
Merge departments team(x), team(x + 1), …, team(y), where x and y (1 ≤ x ≤ y ≤ n) — the numbers of some two employees of the company.
At that the crisis manager can sometimes wonder whether employees x and y (1 ≤ x, y ≤ n) work at the same department.
Help the crisis manager and answer all of his queries.

Input
The first line of the input contains two integers n and q (1 ≤ n ≤ 200 000, 1 ≤ q ≤ 500 000) — the number of the employees of the company and the number of queries the crisis manager has.
Next q lines contain the queries of the crisis manager. Each query looks like type x y, where . If type = 1 or type = 2, then the query represents the decision of a crisis manager about merging departments of the first and second types respectively. If type = 3, then your task is to determine whether employees x and y work at the same department. Note that x can be equal to y in the query of any type.

Output
For each question of type 3 print “YES” or “NO” (without the quotes), depending on whether the corresponding people work in the same department.

Examples
Input
8 6
3 2 5
1 2 5
3 2 5
2 4 7
2 1 2
3 1 7
Output
NO
YES
YES

题目大意:一个公司有n个人n个部门,要合并部门。有两种方式合并,一种是序号x和y两个部门直接合并,x和y是部门中的某个成员;二是序号x到y的一系列部门合并。
三是对x和y两个成员查询是否在同一个部门。

思路:并查集问题。难点在于第二种合并方式,区间合并。
解决方式是,维护一个next数组,保存当前部门的下一个部门。对每次的区间合并都维护一下next数组,这样每次的区间合并可以跳过大部分已经被合并的部门,是一种动态的更新过程。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

const int N=200005;
int fa[N],nextt[N];      //根数组和 下一个部门的数组
int n;
 
void init(){
	for(int i=0;i<=n;i++){ //初始化
		fa[i]=i;
		nextt[i]=i+1;  //开始每个保存它的下一个       
	}
}
int find(int x){
	if(fa[x]==x){
		return x;
	}
	return fa[x]=find(fa[x]);
}

void merge(int x,int y){
	int xx=find(x),yy=find(y);
	if(xx!=yy){
		fa[xx]=yy; 
	}
}

int main(){
	int q;
	scanf("%d%d",&n,&q);
	
	init();
	while(q--){
		int c,x,y;
		scanf("%d%d%d",&c,&x,&y);
		if(c==1){
			merge(x,y);
		}else if(c==2){
			int t;
			for(int i=x+1;i<=y;i=t){
				merge(i-1,i);
				t=nextt[i];          
				nextt[i]=nextt[y];  //更新为右端点的下一个
			}
		}else{
			int fx=find(x),fy=find(y);
			if(fx==fy){
				printf("YES\n");
			}else{
				printf("NO\n");
			}
		}
	}
	return 0;
}

一开始把题意理解成了,合并人数为x到y的部门,傻傻的搞了半天按秩合并,哈哈哈。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清辉依次减

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值