知道了并查集写的问题后,我也明白了为什么之前这道题TLE的原因;
有这道题的合并操作不难想到用并查集维护;
由于并查集易于向上查询而不易于向下查询
所以对于询问方块x下面有多少个方块,我们可以转化为立方柱的规模-x上方的方块数-1
所以我们可以再维护这两个域即可
1 var fa,s,up:array[0..300010] of longint; 2 k1,k2,m,n,x,y,i:longint; 3 ch:char; 4 5 function getf(x:longint):longint; 6 var f:longint; 7 begin 8 if fa[x]<>x then 9 begin 10 f:=getf(fa[x]); 11 up[x]:=up[x]+up[fa[x]]; 12 fa[x]:=f; 13 end; 14 exit(fa[x]); 15 end; 16 17 function getu(x:longint):longint; 18 begin 19 k2:=0; 20 while fa[x]<>x do 21 begin 22 k2:=k2+up[x]; 23 x:=fa[x]; 24 end; 25 exit(x); 26 end; 27 28 begin 29 readln(m); 30 for i:=1 to 300000 do 31 begin 32 fa[i]:=i; 33 s[i]:=1; 34 up[i]:=0; 35 end; 36 for i:=1 to m do 37 begin 38 read(ch); 39 if ch='M' then 40 begin 41 readln(x,y); 42 k1:=getf(x); 43 k2:=getf(y); 44 fa[k2]:=k1; 45 up[k2]:=s[k1]; 46 s[k1]:=s[k1]+s[k2]; 47 end 48 else begin 49 readln(x); 50 k1:=getu(x); 51 writeln(s[k1]-k2-1); 52 end; 53 end; 54 end.