Give you a Set
2015-07-17 11:19
411 查看
Give you a Set
Description
给你n个初始集合:{1}, {2}, {3}, …, {n}.,即每个集合中只有1个元素,第i(1<=i<=n)个集合中含有元素i。现在我们要对这n个集合做一些有趣的操作:
操作1:1 p q
解释: 合并 p 元素与q元素所在集合,如果p与q已经在一个相同的集合中了,忽略这个操作
操作 2:2 p q
解释 :把元素 p 移动到 元素 q 所在集合,如果p与q已经在一个相同的集合中了,忽略这个操作
操作 3: 3 p
解释 :返回包含元素p的集合的元素个数与该集合元素的总和
Input
输入有许多测试用例,每个测试用例第一行为n与m( 1 <=n,m<=100000 ),分别代表初始集合的总数,与 操作总数。以下m行为m个操作,保证操作合法,即1<=p,q<=n。输入到文件尾。输入文件大小不超过 5 M。
Output
对于每个操作3,输出两个整数:该集合元素的个数 与 集合中元素的总和。
Sample Input
5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
Sample Output
3 12
3 7
2 8
Hint
初始集合:{1}, {2}, {3}, {4}, {5}
操作 1 1 2 后 :{1,2}, {3}, {4}, {5}
操作 2 3 4 后 :{1,2}, {3,4}, {5}( 忽略空集合 )
操作 1 3 5 后 :{1,2}, {3,4,5}
操作 2 4 1 后 :{1,2,4}, {3,5}
Description
给你n个初始集合:{1}, {2}, {3}, …, {n}.,即每个集合中只有1个元素,第i(1<=i<=n)个集合中含有元素i。现在我们要对这n个集合做一些有趣的操作:
操作1:1 p q
解释: 合并 p 元素与q元素所在集合,如果p与q已经在一个相同的集合中了,忽略这个操作
操作 2:2 p q
解释 :把元素 p 移动到 元素 q 所在集合,如果p与q已经在一个相同的集合中了,忽略这个操作
操作 3: 3 p
解释 :返回包含元素p的集合的元素个数与该集合元素的总和
Input
输入有许多测试用例,每个测试用例第一行为n与m( 1 <=n,m<=100000 ),分别代表初始集合的总数,与 操作总数。以下m行为m个操作,保证操作合法,即1<=p,q<=n。输入到文件尾。输入文件大小不超过 5 M。
Output
对于每个操作3,输出两个整数:该集合元素的个数 与 集合中元素的总和。
Sample Input
5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
Sample Output
3 12
3 7
2 8
Hint
初始集合:{1}, {2}, {3}, {4}, {5}
操作 1 1 2 后 :{1,2}, {3}, {4}, {5}
操作 2 3 4 后 :{1,2}, {3,4}, {5}( 忽略空集合 )
操作 1 3 5 后 :{1,2}, {3,4,5}
操作 2 4 1 后 :{1,2,4}, {3,5}
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; #define N 200010 int father ,num ; int sum ; int n,m; int find(int a) { int r=a; while(father[r]!=r) r=father[r]; for(int l=a,t;l!=r;l=t) { t=father[l]; father[l]=r; } return r; } void merge(int a,int b) { int aa=find(a),bb=find(b); if(aa==bb) return ; int m=min(aa,bb); father[aa]=father[a]=m;father[bb]=father[b]=m; sum[aa]+=sum[bb];sum[bb]=sum[aa]; num[aa]+=num[bb];num[bb]=num[aa]; } void link(int a,int b) { int aa=find(a),bb=find(b); if(aa==bb) return ; father[a]=bb; num[aa]--,num[bb]++; sum[aa]-=a,sum[bb]+=a; } void query(int a) { int aa=find(a); printf("%d %d\n",num[aa],sum[aa]); } void init() { for(int i=1;i<=n;i++) { father[i]=n+i; } for(int i=n+1;i<=2*n;i++) { father[i]=i; } for(int i=n+1;i<=2*n;i++) { num[i]=1; sum[i]=i-n; } } int main() { //freopen("in.txt","r",stdin); while(scanf("%d %d",&n,&m)!=EOF) { init(); int c,a,b; while(m--) { scanf("%d",&c); switch(c) { case 1:scanf("%d %d",&a,&b);merge(a,b);break; case 2:scanf("%d %d",&a,&b);link(a,b);break; case 3:scanf("%d",&a);query(a);break; default:; } } } return 0; }
相关文章推荐
- 关于寻路算法的一些思考(2):Heuristics 函数
- 为什么SVN有时候检测不出Unity Profab的修改
- 三个思路来实现自己定义404页面
- 为什么国外程序员爱用Mac?
- [LeetCode][Java] Add Binary
- Ajax实例讲解与技术原理
- PC问题-使用BAT方法清理Delphi临时文件
- 键盘,鼠标,文件
- C# in depth ( 第二章 C#1.0所搭建的核心基础)
- *Looksery Cup 2015 C. The Game Of Parity
- Longest Palindromic Substring
- 【Hibernate八】HQL之单表查询
- js获取int类型数字,长度过长出现错误
- 1154_Give you a Bag
- Git学习
- 解决ListView滑动时出现黑边的问题
- 关于寻路算法的一些思考(1):A*算法介绍
- secureCRT自动断开解决方法
- C++中的构造函数的用法
- 画布.画笔.画刷