Description
There are n nodes, labeled from 1 to N, which are disconnected from each other at the beginning. The initial weight of the ith node is a[i], and then there are some operations as follows:
U x y: add an edge to connect the x-th and y-th nodes
A1 x v: increase the weight of node X by v
A2 x v: increase the weight of all nodes in the connected block where the x-th node is located by v
A3 v: increase the weight of all nodes by v
F1 x: output the current weight of node x
F2 x: output the weight of the node with the largest weight in the connected block where the x-th node is located
F3: output the weight of the node with the largest weight among all nodes
Input
The first line of input is an integer N, representing the number of nodes.
Next, enter n integers, a[1], a[2] , a[N], representing the initial weight of N nodes.
Enter an integer Q on the next line to represent the next operand.
Finally, input line Q, the format of each line is as shown in the title description.
Output
For operations F1, F2, F3, output the corresponding results, each result occupies one line.
Sample Input
3
0 0 0
8
A1 3 -20
A1 2 20
U 1 3
A2 1 10
F1 3
F2 3
A3 -10
F3
Sample Output
-10
10
10
HINT
For 30% data, guarantee n < = 100, Q < = 10000
For 80% data, guarantee n < = 100000, Q < = 100000
For 100% data, guarantee n < = 300000, Q < = 300000
For all data, ensure that the input is legal and - 1000 < = V, a [1], a [2] , a[N]<=1000
Code
#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define mod 65537
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=300005;
int n,Q,add;
int a[N],q[N],fa[N],ls[N],rs[N],tag[N],tot;
multiset<int>s;
int find(int x)
{
while (fa[x]) x=fa[x];
return x;
}
void pushdown(int x)
{
if(!tag[x])return;
int t=tag[x],l=ls[x],r=rs[x];
tag[x]=0;
if(l)tag[l]+=t,a[l]+=t;
if(r)tag[r]+=t,a[r]+=t;
}
int merge(int x,int y)
{
if (!x) return y;
if (!y) return x;
if (a[x]<a[y]) swap(x,y);
pushdown(x);
rs[x]=merge(rs[x],y);
fa[rs[x]]=x;
swap(ls[x],rs[x]);
return x;
}
void pushtag(int x)
{
while(x)q[++tot]=x,x=fa[x];
while(tot)pushdown(q[tot--]);
}
int del(int x)
{
pushtag(x);
int f=fa[x],t=merge(ls[x],rs[x]);
ls[x]=rs[x]=fa[x]=0;
if (x==ls[f]) ls[f]=t;else rs[f]=t;
fa[t]=f;
return find(t);
}
int main()
{
n=read();for (int i=1;i<=n;i++) a[i]=read(),s.insert(a[i]);
Q=read();
while (Q--)
{
char ch[5];scanf("%s",ch);
if (ch[0]=='U')
{
int x=find(read()),y=find(read());
if (x!=y)
{
if (merge(x,y)==x)s.erase(s.find(a[y]));
else s.erase(s.find(a[x]));
}
}
else if (ch[0]=='A')
{
if (ch[1]=='1')
{
int x=read(),v=read();
pushtag(x);s.erase(s.find(a[find(x)]));
a[x]+=v;
s.insert(a[merge(x,del(x))]);
}
else if (ch[1]=='2')
{
int x=read(),v=read(),f=find(x);
tag[f]+=v;a[f]+=v;
s.erase(s.find(a[f]-v));s.insert(a[f]);
}
else
{
int v=read();add+=v;
}
}
else
{
if (ch[1]=='1')
{
int x=read();pushtag(x);printf("%d\n",a[x]+add);
}
else if (ch[1]=='2')
{
int x=read(),f=find(x);printf("%d\n",a[f]+add);
}
else printf("%d\n",*--s.find(inf)+add);
}
}
return 0;
}