好题,先离线把连通块变成连续的区间
每次连通块合并就相当于两个区间合并
这样就轻易的用线段树解决了
1 type node=record 2 wh:string[2]; 3 x,y:longint; 4 end; 5 6 var lazy,tree:array[0..300010*4] of longint; 7 q:array[0..300010] of node; 8 a,b,c,last,next,fa:array[0..300010] of longint; 9 i,n,m,x,y,t:longint; 10 ch:char; 11 12 procedure swap(var a,b:longint); 13 var c:longint; 14 begin 15 c:=a; 16 a:=b; 17 b:=c; 18 end; 19 20 function max(a,b:longint):longint; 21 begin 22 if a>b then exit(a) else exit(b); 23 end; 24 25 function getf(x:longint):longint; 26 begin 27 if fa[x]<>x then fa[x]:=getf(fa[x]); 28 exit(fa[x]); 29 end; 30 31 procedure push(i:longint); 32 begin 33 inc(lazy[i*2],lazy[i]); 34 inc(tree[i*2],lazy[i]); 35 inc(lazy[i*2+1],lazy[i]); 36 inc(tree[i*2+1],lazy[i]); 37 lazy[i]:=0; 38 end; 39 40 function ask(i,l,r,x,y:longint):longint; 41 var m,s:longint; 42 begin 43 if (x<=l) and (y>=r) then exit(tree[i]) 44 else begin 45 if lazy[i]<>0 then push(i); 46 m:=(l+r) shr 1; 47 s:=-2147483647; 48 if x<=m then s:=ask(i*2,l,m,x,y); 49 if y>m then s:=max(s,ask(i*2+1,m+1,r,x,y)); 50 exit(s); 51 end; 52 end; 53 54 procedure add(i,l,r,x,y,z:longint); 55 var m:longint; 56 begin 57 if (x<=l) and (y>=r) then 58 begin 59 inc(tree[i],z); 60 inc(lazy[i],z); 61 end 62 else begin 63 if lazy[i]<>0 then push(i); 64 m:=(l+r) shr 1; 65 if x<=m then add(i*2,l,m,x,y,z); 66 if y>m then add(i*2+1,m+1,r,x,y,z); 67 tree[i]:=max(tree[i*2],tree[i*2+1]); 68 end; 69 end; 70 71 procedure build(i,l,r:longint); 72 var m:longint; 73 begin 74 if l=r then tree[i]:=a[c[l]] 75 else begin 76 m:=(l+r) shr 1; 77 build(i*2,l,m); 78 build(i*2+1,m+1,r); 79 tree[i]:=max(tree[i*2],tree[i*2+1]); 80 end; 81 end; 82 83 begin 84 readln(n); 85 for i:=1 to n do 86 begin 87 read(a[i]); 88 fa[i]:=i; 89 last[i]:=i; 90 end; 91 readln(m); 92 for i:=1 to m do 93 begin 94 read(ch); 95 q[i].wh:=ch; 96 read(ch); 97 q[i].wh:=q[i].wh+ch; 98 if q[i].wh='U ' then 99 begin 100 readln(q[i].x,q[i].y); 101 x:=getf(q[i].x); 102 y:=getf(q[i].y); 103 if x=y then continue; 104 fa[y]:=x; 105 next[last[x]]:=y; 106 last[x]:=last[y]; 107 end 108 else if (q[i].wh='A1') or (q[i].wh='A2') then 109 readln(q[i].x,q[i].y) 110 else if (q[i].wh='F3') then readln 111 else readln(q[i].x); 112 end; 113 114 for i:=1 to n do 115 if fa[i]=i then 116 begin 117 x:=i; 118 while x<>0 do 119 begin 120 inc(t); 121 b[x]:=t; 122 c[t]:=x; 123 x:=next[x]; 124 end; 125 end; 126 127 build(1,1,n); 128 for i:=1 to n do 129 begin 130 fa[i]:=i; 131 last[i]:=i; 132 end; 133 134 for i:=1 to m do 135 if q[i].wh='U ' then 136 begin 137 x:=getf(q[i].x); 138 y:=getf(q[i].y); 139 if x=y then continue; 140 fa[y]:=x; 141 last[x]:=last[y]; 142 end 143 else if q[i].wh='A1' then 144 add(1,1,n,b[q[i].x],b[q[i].x],q[i].y) 145 else if q[i].wh='A2' then 146 begin 147 x:=getf(q[i].x); 148 y:=last[x]; 149 add(1,1,n,b[x],b[y],q[i].y); 150 end 151 else if q[i].wh='A3' then 152 begin 153 inc(tree[1],q[i].x); 154 inc(lazy[1],q[i].x); 155 end 156 else if q[i].wh='F1' then 157 writeln(ask(1,1,n,b[q[i].x],b[q[i].x])) 158 else if q[i].wh='F2' then 159 begin 160 x:=getf(q[i].x); 161 y:=last[x]; 162 writeln(ask(1,1,n,b[x],b[y])); 163 end 164 else writeln(tree[1]); 165 end.