知道了并查集写的问题后,我也明白了为什么之前这道题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.
View Code

 

posted on 2014-07-19 13:21  acphile  阅读(120)  评论(0编辑  收藏  举报