网上都是可并堆在线搞,其实直接离线处理处每个联通块,然后把他们放一起,然后点更新,区间询问就可以了。
#include
#include
#include
#include
using namespace std;
#define INF 100000000
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define getmid int mid=(l+r)>>1
#define maxn 1200000
int tree[maxn],add[maxn];
int n,m,a[maxn],save[maxn];
int next[maxn],id,w[maxn],ed[maxn],fa[maxn];
struct Q
{
int o,x,y;
void scan()
{
char s[3];
scanf("%s",s);
if(*s=='U')
scanf("%d %d",&x,&y),o=1;
else if(*s=='A'&&s[1]=='1')
scanf("%d %d",&x,&y),o=2;
else if(*s=='A'&&s[1]=='2')
scanf("%d %d",&x,&y),o=3;
else if(*s=='A'&&s[1]=='3')
scanf("%d",&x),o=4;
else if(*s=='F'&&s[1]=='1')
scanf("%d",&x),o=5;
else if(*s=='F'&&s[1]=='2')
scanf("%d",&x),o=6;
else if(*s=='F'&&s[1]=='3')
o=7;
}
}q[300020];
void pushup(int rt)
{
tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
void pushdown(int rt)
{
if(add[rt])
{
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
tree[rt<<1]+=add[rt];
tree[rt<<1|1]+=add[rt];
add[rt]=0;
}
}
void update(int l,int r,int rt,int x,int y,int v)
{
if(x<=l&&r<=y)
{
add[rt]+=v;
tree[rt]+=v;
return;
}
pushdown(rt);
getmid;
if(x<=mid) update(lson,x,y,v);
if(y>mid) update(rson,x,y,v);
pushup(rt);
}
int qmax(int l,int r,int rt,int x,int y)
{
if(x<=l&&r<=y)
{
return tree[rt];
}
pushdown(rt);
getmid;
int ans=-INF;
if(x<=mid) ans=max(ans,qmax(lson,x,y));
if(y>mid) ans=max(ans,qmax(rson,x,y));
return ans;
}
void build(int l,int r,int rt)
{
if(l==r)
{
tree[rt]=save[l];
return;
}
getmid;
build(lson);
build(rson);
pushup(rt);
}
int getf(int x)
{
return fa[x]==x?x:fa[x]=getf(fa[x]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
fa[i]=i,ed[i]=i;
scanf("%d",&m);
int r1,r2;
for(int i=1;i<=m;i++)
{
q[i].scan();
if(q[i].o==1)
{
r1=getf(q[i].x);r2=getf(q[i].y);
if(r1==r2) continue;
fa[r2]=r1;
next[ed[r1]]=r2;
ed[r1]=ed[r2];
}
}
for(int i=1;i<=n;i++)
{
if(getf(i)==i)
{
for(int j=i;j;j=next[j])
{
id++;w[j]=id;save[id]=a[j];
}
}
}
build(1,n,1);
/*
for(int i=1;i<=n;i++)
{
printf("%d ",save[i]);
printf("%d\n",qmax(1,n,1,w[i],w[i]));
}
*/
for(int i=1;i<=n;i++)
{
fa[i]=i;ed[i]=i;
}
for(int i=1;i<=m;i++)
{
if(q[i].o==1)
{
r1=getf(q[i].x);r2=getf(q[i].y);
if(r1==r2)
continue;
fa[r2]=r1;
ed[r1]=ed[r2] ;
}
else if(q[i].o==2)
update(1,n,1,w[q[i].x],w[q[i].x],q[i].y);
else if(q[i].o==3)
update(1,n,1,w[getf(q[i].x)],w[ed[getf(q[i].x)]],q[i].y);
else if(q[i].o==4)
update(1,n,1,1,n,q[i].x);
else if(q[i].o==5)
printf("%d\n",qmax(1,n,1,w[q[i].x],w[q[i].x]));
else if(q[i].o==6)
printf("%d\n",qmax(1,n,1,w[getf(q[i].x)],w[ed[getf(q[i].x)]]));
else if(q[i].o==7)
printf("%d\n",qmax(1,n,1,1,n));
}
return 0;
}