Building Block

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5426 Accepted Submission(s): 1663

Problem Description
John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:

M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
C X : Count the number of blocks under block X

You are request to find out the output for each C operation.

Input
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.

Output
Output the count for each C operations in one line.

Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

Sample Output
1
0
2

路径压缩的并查集。对每个点x,rank[x]记录到父亲的距离,size[x]表示以x为根节点的子树大小。x下边的积木数=x的最高级父亲father的size-Σ(从x到father的路径上各点的rank)。路径压缩这里写的有点意识模糊,居然一遍AC,提交完自己都挺奇怪,这就过了啊......

#include <stdio.h>
#include <string.h>
int tmpx;
int size[], rank[];
class Union_Find_Set {
#define MAX_UNION_FIND_SET_SIZE 30005
public:
int setSize;
int father[MAX_UNION_FIND_SET_SIZE];
Union_Find_Set() {
setSize = ;
}
Union_Find_Set(int x) {
setSize = x;
clear(x);
}
void clear(int x) {
for (int i = ; i < x; i++) {
father[i] = i;
}
}
int getFather(int x) {
tmpx = ;
int ret = x, tmp;
while (ret != father[ret]) {
tmpx += (rank[ret]);
ret = father[ret];
}
int tmpz = tmpx;
while (x != father[x]) {
tmp = father[x];
father[x] = ret;
tmpz -= rank[x];
rank[x] += tmpz;
x = tmp;
}
return ret;
}
bool merge(int a, int b) {
a = getFather(a);
b = getFather(b);
if (a != b) {
father[b] = a;
rank[b] = size[a] + ;
size[a] += (size[b] + );
return true;
} else {
return false;
}
}
int countRoot() {
int ret = ;
for (int i = ; i < setSize; i++) {
if (father[i] = i) {
ret++;
}
}
return ret;
}
}; Union_Find_Set ufs;
int main() {
int n, a, b;
char q;
while (scanf("%d", &n) != EOF) {
memset(size, , sizeof(size));
memset(rank, , sizeof(rank));
ufs.clear();
while (n--) {
getchar();
scanf("%c", &q);
if (q == 'M') {
scanf("%d%d", &a, &b);
ufs.merge(a, b);
} else if (q == 'C') {
scanf("%d", &a);
printf("%d\n", size[ufs.getFather(a)] - tmpx);
}
}
}
return ;
}

最新文章

  1. Entity Framework 6 Database-first连接Oracle11g
  2. Android中的多线程编程
  3. [5] 智能指针boost::shared_ptr
  4. codeforces A. Candy Bags 解题报告
  5. HDU 3685 Rotational Painting(多边形质心+凸包)(2010 Asia Hangzhou Regional Contest)
  6. css 样式大全
  7. ebj笔记
  8. oracle中比较两表表结构差异和数据差异的方法
  9. 最短路径算法之二——Dijkstra算法
  10. Ubuntu 安装Chrome步骤
  11. 2013多校联合2 I Warm up 2(hdu 4619)
  12. SpringBoot入坑-配置文件使用
  13. java常用类介绍
  14. Spring Cloud Config 自动刷新所有节点 架构改造
  15. HTML表格的运用
  16. tomcat源码阅读之日志记录器(Logger)
  17. 编写函数digit(num, k),函数功能是:求整数num从右边开始的第k位数字的值,如果num位数不足k位则返回0。
  18. GUC-6 Callable 接口
  19. shell 判断日期间隔及润年
  20. 用python自建一个DNS服务器

热门文章

  1. 安装pywin32
  2. 软件开发的MVC构架
  3. kinect:0x80080014
  4. MySQL_视图/触发器/事务/存储过程/函数
  5. javaee的toString的用法
  6. 路飞学城Python-Day100
  7. priority_deque作为Timer时间队列底层容器的一些思考
  8. loadrunner笔记----好记性不如烂笔头
  9. Windows GUI程序自动化之pywinauto
  10. HDU 5322 Hope (分治NTT优化DP)