1 #include<cstdio>
2 #include<math.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<cstring>
7 using namespace std;
8 const int maxn=302333;
9 struct zs1{
10 int c[2],dis,val,fa;
11 int add;
12 }tree[maxn];
13 struct zs2{
14 int c[2],dis,val,fa;
15 }tree1[maxn];
16 int i,j,k,n,m,alladd,x,y,q,root1,tmpp;
17 int stack[maxn];
18 char id[2333];
19
20 int getroot(int x){
21 while(tree[x].fa)x=tree[x].fa;return x;
22 }
23 void pushdown(int x){
24 if(tree[x].add==0)return;
25 int l=tree[x].c[0],r=tree[x].c[1],add=tree[x].add;
26 if(l)tree[l].add+=add,tree[l].val+=add;
27 if(r)tree[r].add+=add,tree[r].val+=add;
28 tree[x].add=0;
29 }
30 void pushalldown(int x){
31 int top=0;
32 while(x)stack[++top]=x,x=tree[x].fa;
33 for(;top;top--)pushdown(stack[top]);
34 }
35 int merge1(int a,int b){
36 if(a==0||b==0)return a+b;
37 if(tree1[a].val<tree1[b].val)swap(a,b);
38 tree1[a].c[1]=merge1(tree1[a].c[1],b);
39 int l=tree1[a].c[0],r=tree1[a].c[1];
40 tree1[r].fa=a;
41 if(tree1[l].dis<tree1[r].dis)swap(tree1[a].c[0],tree1[a].c[1]);
42 tree1[a].dis=tree1[r].dis+1;
43 return a;
44 }
45 void del1(int x){
46 int fa=tree1[x].fa,newson=merge1(tree1[x].c[0],tree1[x].c[1]);
47 tree1[x].fa=tree1[x].c[0]=tree1[x].c[1]=0;
48 if(newson)tree1[newson].fa=fa;
49 if(fa){
50 tree1[fa].c[tree1[fa].c[1]==x]=newson;
51 while(fa){
52 int pre=tree1[fa].dis;
53 if(tree1[tree1[fa].c[1]].dis>tree1[tree1[fa].c[0]].dis)swap(tree1[fa].c[0],tree1[fa].c[1]);
54 tree1[fa].dis=tree1[tree1[fa].c[1]].dis+1;
55 if(tree1[fa].dis==pre)break;
56 fa=tree1[fa].fa;
57 }
58 }
59 else root1=newson;
60 }
61 int merge(int a,int b){
62 if(a==0||b==0)return a+b;
63 if(tree[a].val<tree[b].val)swap(a,b);
64 pushdown(a);
65 tree[a].c[1]=merge(tree[a].c[1],b);
66 int l=tree[a].c[0],r=tree[a].c[1];
67 tree[r].fa=a;
68 if(tree[l].dis<tree[r].dis)swap(tree[a].c[0],tree[a].c[1]);
69 tree[a].dis=tree[tree[a].c[1]].dis+1;
70 return a;
71 }
72 void del(int x){
73 pushalldown(x);
74 int newson=merge(tree[x].c[0],tree[x].c[1]),fa=tree[x].fa;
75 tree[x].c[0]=tree[x].c[1]=tree[x].fa=0;
76 if(newson)tree[newson].fa=fa;
77 if(!fa)tmpp=getroot(newson);else tmpp=getroot(fa);
78 if(fa){
79 tree[fa].c[tree[fa].c[1]==x]=newson;
80 while(fa&&tree[fa].c[1]){
81 int pre=tree[fa].dis;
82 if(tree[tree[fa].c[1]].dis>tree[tree[fa].c[0]].dis)swap(tree[fa].c[0],tree[fa].c[1]);
83 tree[fa].dis=tree[tree[fa].c[1]].dis+1;
84 if(tree[fa].dis==pre)break;
85 fa=tree[fa].fa;
86 }
87 }
88 //if(newson)tmpp=getroot(newson);
89 //else tmpp=getroot(fa);//这里是错的,如果维护距离的时候fa跑到了0节点就会挂TAT
90 }
91 void runA1(int x,int v){
92 pushalldown(x);
93 int preroot=getroot(x);
94 int fa=tree[x].fa;
95 del(x);
96 tree[x].val+=v;
97 merge(tmpp,x);
98 int nowroot=getroot(x);
99 if(nowroot!=preroot||fa==0){
100 del1(preroot);
101 tree1[nowroot].val=tree[nowroot].val;
102 root1=merge1(root1,nowroot);
103 }
104 }
105 void runU(int x,int y){
106 int t[2];
107 t[0]=getroot(x);t[1]=getroot(y);
108 if(t[0]!=t[1])
109 del1(t[t[0]==merge(t[0],t[1])]);
110 }
111 void runA2(int x,int y){
112 x=getroot(x);
113 tree[x].add+=y;tree[x].val+=y;
114 del1(x);
115 tree1[x].val=tree[x].val;
116 root1=merge1(root1,x);
117 }
118 int main(){
119 tree[0].dis=tree1[0].dis=-1;
120 tree[0].val=-1233333333;
121 scanf("%d",&n);
122 for(i=1;i<=n;i++)scanf("%d",&tree[i].val),tree1[i].val=tree[i].val;
123 for(i=1;i<=n;i++)root1=merge1(root1,i);
124 scanf("%d",&q);
125 while(q--){
126 scanf("%s",id);
127 if(id[0]==‘U‘){
128 scanf("%d%d",&x,&y);
129 runU(x,y);
130 }else
131 if(id[0]==‘A‘){
132 scanf("%d",&x);if(id[1]!=‘3‘)scanf("%d",&y);
133 if(id[1]==‘1‘)runA1(x,y);
134 if(id[1]==‘2‘)runA2(x,y);
135 if(id[1]==‘3‘)alladd+=x;
136 }else
137 if(id[0]==‘F‘){
138 if(id[1]!=‘3‘)scanf("%d",&x);
139 if(id[1]==‘1‘){
140 pushalldown(x);
141 printf("%d\n",tree[x].val+alladd);
142 }
143 if(id[1]==‘2‘)printf("%d\n",tree[getroot(x)].val+alladd);
144 if(id[1]==‘3‘)printf("%d\n",tree1[root1].val+alladd);
145 }
146 }
147 return 0;
148 }