用的并查集思路,加上邻接表判断顺序先后(虽然是TLE的)
#include<bits/stdc++.h>
using namespace std;
int n,m,a[202000],s[202000],fa[202000],l[202000][100],nd[2020000],X,Y;//邻接表
char c;
int fin(int x){ //主元
if(fa[x]==x) return x;
return fin(fa[x]);
}
int q(int x,int son,int p){ //求和
if(x==son) return p;
int cnt=1;
while(l[x][cnt]!=son) cnt++;
cnt++;
for(;cnt<=nd[x];cnt++) p+=s[l[x][cnt]];
return q(fa[x],x,p);
}
void M(int x,int y){
int u,v;
u=fin(x),v=fin(y);
if(u==v) return;
fa[u]=v;
l[v][++nd[v]]=u;
s[v]+=s[u];
}
void D(int x,int son){
if(x==son) return;
int cnt=1,u;
while(l[x][cnt]!=son) cnt++;
u=cnt;
cnt++;
for(;cnt<=nd[x];cnt++){
fa[l[x][cnt]]=X;
s[X]+=s[l[x][cnt]];
l[X][++nd[X]]=l[x][cnt];
}
nd[x]=u;
s[x]-=s[X];
D(fa[x],x);
}
int Q(int x,int y){
if(fin(x)!=fin(y)) return -1;
int u=q(fa[x],x,s[x]),v=q(fa[y],y,s[y]);
if(u>v) return u-v+a[y];
return v-u+a[x];
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) s[i]=a[i],fa[i]=i;
for(int i=1;i<=m;i++){
cin>>c;
if(c=='M'){
cin>>X>>Y;
M(X,Y);
}else if(c=='D'){
cin>>X;
D(fa[X],X);
fa[X]=X;
}else{
cin>>X>>Y;
cout<<Q(X,Y)<<endl;
}
}
return 0;
}