N

1有标号为1到n的n个龙珠,分别放在对应标号为1到n的n个城市里。 2下面有两种操作: 3T A B表示把A龙珠所在城市的所有龙珠都转移到B龙珠所在的城市中 4Q A 表示查询A,需要知道A龙珠现在所在的城市,A所在的城市有几颗龙珠,A转移到这个城市移动了多少次,分别输出3个整数,表示上述信息。

前两个用普通并查集就能算出来,移动次数不好维护;

如果我们不进行路径压缩,那么查询点的深度即是移动的次数,因为每移动一次父节点就下降一层,深度+1;

但不路径压缩的话就会超时,所以我们要把点的深度记录下来;;

1#include <cstdio> 2#include <algorithm> 3#include <iostream> 4 5using namespace std; 6int ans[100000] ,ansn[100000] ,pre[100000]; 7 8void init( int x){ 9 for( int i = 0 ; i<=x ;i++){ 10 pre[i] = i; 11 ans[i] = 0; 12 ansn[i] = 1; 13 } 14} 15 16int find( int a){ 17 /* int r=a; //刚开始这样记录深度ans[a],但是这样不对,这样只是路径压缩一次ans[n]++,但实际上一次可能压缩很多层,所以应该是加上上一层的压缩层数 18 while( pre[a]!=a){ 19 a=pre[a]; 20 } 21 int t; 22 while( pre[r]!=a){ 23 ans[r]++; 24 t= pre[r]; 25 pre[r] =a; 26 r=t; 27 }*/ 28 if( a == pre[a] )return a; 29 else{ 30 int tmp= pre[a]; 31 pre[a] = find( pre[a]); 32 ans[a] += ans[tmp]; 33 } 34 return pre[a]; 35} 36 37int add( int a ,int b){ 38 int x=find(a); 39 int y=find(b); 40 if( x != y){ 41 pre[x] = y; 42 ans[x] = 1; 43 ansn[y] += ansn[x]; 44 ansn[x] =0; 45 } 46} 47 48int main( ){ 49 int ks=0, T; 50 scanf("%d",&T); 51 while( T--){ 52 printf("Case %d:\n",++ks); 53 int n,m; 54 scanf("%d%d" ,&n ,&m); 55 init( n); 56 while( m--){ 57 char op[10]; 58 int a,b; 59 scanf("%s",op); 60 if( op[0] == 'T'){ 61 scanf("%d%d" ,&a,&b); 62 add( a,b); 63 } 64 if( op[0] == 'Q'){ 65 scanf("%d" ,&a); 66 int b=find(a); 67 printf("%d %d %d\n" ,b ,ansn[b] ,ans[a]); 68 } 69 } 70 } 71 return 0; 72}
点赞
收藏

评论区

加载中...

相关推荐

python刷题-序列求和

问题描述求123...n的值。输入格式输入包括一个整数n。输出格式输出一行,包括一个整数,表示123...n的值。样例输入4样例输出10样例输入100说明:有一些试题会给出多组样例输入输出以帮助你更好的做题。一般在提交之前所有这些样例都需要测试通过才行,但这不代表这几组样例数据都正确了你的程序就是完全正确的,潜在的错误可能仍然导致你的得分较低

python刷题-字母图形

问题描述利用字母可以组成一些美丽的图形,下面给出了一个例子:ABCDEFGBABCDEFCBABCDEDCBABCDEDCBABC这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。输入格式输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。输出格式输出n行,每个m个字符,为你的图形。样例输入57样例输

C 语言代码大全

1两个数组的合并题目描述已知数组a中有m个按升序排列的元素,数组b中有n个按降序排列的元素,编程将a与b中的所有元素按降序存入数组c中。输入输入有两行,第一行首先是一个正整数m,然后是m个整数;第二行首先是一个正整数n,然后是n个整数,m,n均小于等于1000000。输出输出合并后的mn个整数,数据之间用空格隔开。输出占一行。样例输入4

python刷题-最大最小公倍数

问题描述已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。输入格式输入一个正整数N。输出格式输出一个整数,表示你找到的最小公倍数。样例输入9样例输出504数据规模与约定1<N<106。Nint(input())Min1ifN<2:print(N)elifN%2

python-阶乘计算

问题描述  输入一个正整数n,输出n的值。  其中n123…n。算法描述  n可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A0表示a的个位,A1表示a的十位,依次类推。  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。  首先将a设为1,然后乘2,

python刷题-进制转换

十六进制转八进制问题描述  给定n个十六进制正整数,输出它们对应的八进制数。输入格式  输入的第一行为一个正整数n(1<n<10)。  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。输出格式  输出n行,每行为输入对应的八进制正整数。  【注意】  输入的十六进制数不会有