题意:

n块积木,m个操作或询问。每次移动积木的时候,约翰会选择两块积木X,Y,把X搬到Y的上方。如果X已经和其它积木叠在一起了,那么应将这叠积木整体移动到Y的上方;如果Y已经和其它积木叠在一起了的,假设在Y上方最高处的积木为Z,那么应将X所在的那叠积木移动到Z的上方。
每次询问当前时刻,某一块积木的下方有多少块积木。
n,m<=10^5

题解:

带权并查集。
对于每个点x,维护当前所在并查集(也就是这一堆积木中)最下方的积木d[x],最上方的积木fa[x],x到最上方积木的距离f[x],则下方的积木数=f[d[x]]-f[x]。
带权并查集其实就是在findfa的时候顺便维护一些权值。

代码:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
using namespace std; const int N=;
int n,m,fa[N],f[N],d[N];
char s[]; int findfa(int x)
{
if(fa[x]!=x)
{
int y=fa[x];
fa[x]=findfa(y);
f[x]=f[x]+f[y];
d[x]=d[y];
}
return fa[x];
} int main()
{
// freopen("a.in","r",stdin);
freopen("cubes.in","r",stdin);
freopen("cubes.out","w",stdout);
scanf("%d",&m);n=m;
int x,y;
for(int i=;i<=n;i++) {fa[i]=i;d[i]=i;f[i]=;}
for(int i=;i<=m;i++)
{
scanf("%s",s);
if(s[]=='M')
{
scanf("%d%d",&x,&y);
int xx=findfa(x),yy=findfa(y);
fa[yy]=xx;
f[yy]=f[d[x]]+;
d[xx]=d[yy];
findfa(d[x]);findfa(d[y]);
}
else
{
scanf("%d",&x);
findfa(x);
printf("%d\n",f[d[x]]-f[x]);
}
}
return ;
}

最新文章

  1. openstack api快速入门
  2. Windows10有获取通知,但是就不推送的解决方法
  3. 即时聊天IM之三 XMPP协议客户端库的和Android端框架概述
  4. 34款Firefox渗透测试插件工具
  5. [转]Win7 64位搭建本地SVN服务器 Apache+Subversion
  6. csharp: DataTable Rename ColumnName and remove Column
  7. NFS挂载启动
  8. Python成长之路第二篇(1)_数据类型内置函数用法
  9. QT学习 之 事件与事件过滤器(分为五个层次)
  10. HDU 3696 Farm Game
  11. libpng处理png图片(一)
  12. 数据库Mysql的安装及操作---数据引擎
  13. Objc运行时读取和写入plist文件遇到的问题
  14. Java线程的状态
  15. 浏览器虚拟过程IP插件
  16. Forward团队-爬虫豆瓣top250项目-项目总结
  17. javascript面向对象精要第一章原始类型和引用类型整理精要
  18. 开源.NET界面库
  19. 15款不容错过的前端开发Javascript和css类库 - 2017版本~
  20. 什么时候layoutSubview会被调用

热门文章

  1. 11.22Daily Scrum
  2. VS2005、VS2008中的快捷键、组合键大全
  3. ArrayList遍历(JAVA)
  4. 记一次dll强命名冲突事件
  5. 机器学习——DBN深度信念网络详解(转)
  6. 如何进行Linux Kernel 开发
  7. server2003 必要的系统优化和安全设置
  8. IIS发布 MVC 配置
  9. 第68天:原型prototype方法
  10. Git无法删除文件问题:fatal: pathspec &#39;readme.txt&#39; did not match any files