题目链接

题目就告诉我们要用并查集了,操作1和3用裸的带权并查集就行了,

操作2相当于将p结点从当前树中删除,再插入到q的树中,直接删除的话比较麻烦,不妨把它的“尸体”留在原来的地方,在q的树中插入一个新的点,维护一个指向编号为p点的指针即可

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std; const int MAXN=2000010; int n,q,fa[MAXN],size[MAXN],sum[MAXN],m[MAXN],cnt; inline int read(){
int x=0; char c=getchar();
while(c<'0') c=getchar();
while(c>='0') x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x;
} inline int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
} int main()
{
while(scanf("%d%d",&n,&q)!=EOF){
cnt=n;
for(int i=1;i<=n;++i)
fa[i]=i,size[i]=1,sum[i]=i,m[i]=i;
int op,x,y;
while(q--){
op=read();
if(op==1){
x=read(),y=read();
x=m[x]; y=m[y];
if(find(x)==find(y)) continue;
if(rand()%2) swap(x,y);
size[find(y)]+=size[find(x)];
sum[find(y)]+=sum[find(x)];
fa[find(x)]=find(y);
}
else if(op==2){
int p=read(),q=read();
x=m[p]; y=m[q];
if(find(x)==find(y)) continue;
--size[find(x)];
++size[find(y)];
sum[find(x)]-=p;
sum[find(y)]+=p;
m[p]=++cnt;
fa[cnt]=find(y);
}
else{
x=read(); x=m[x];
printf("%d %d\n",size[find(x)],sum[find(x)]);
}
}
}
return 0;
}

最新文章

  1. OpenGL 学习
  2. Let&#39;s Encrypt这个免费的证书签发服务
  3. 在Android平台下的基于Linux-C 的测试程序
  4. Go support for Android
  5. CDOJ 483 Data Structure Problem DFS
  6. hdu 4602 Partition (概率方法)
  7. php中traits学习笔记
  8. POJ 3660 Cow Contest 弗洛伊德
  9. Docker 三剑客之 Docker Swarm
  10. [DeeplearningAI笔记]改善深层神经网络_深度学习的实用层面1.9_归一化normalization
  11. Redis面试点
  12. swiper轮播在ie浏览器上遇到的显示问题探索
  13. eclipse配置tomcat,让java web项目运行起来!
  14. 64位ubuntu搭建android开发环境问题解决方案
  15. linux下设置计划任务执行python脚本
  16. java 反射原理写了一个赋值和取值通用类
  17. java中常量接口及实现常量接口的利与弊
  18. 如何更改删除window服务?
  19. Inno Setup Winfrom 打包工具
  20. 面经问题总结——django相关

热门文章

  1. timeout超时时长优化和hystrix dashboard可视化分布式系统
  2. test aria2 on windows platform
  3. pandas-10 pd.pivot_table()透视表功能
  4. nrm 工具的使用
  5. 给用过SAP CRM中间件的老哥老姐们讲讲SAP CPI
  6. 基于RBAC模型的权限设计:如何设计系统权限体系?
  7. unnitest+HtmlRunner生成测试报告
  8. unity点击按钮换按钮图标
  9. 【RAC】将RAC备份集恢复为单实例数据库
  10. webdriver切换frame的方法