这是我的代码:
#include<cstdio>
#include<random>
#define _N_ 200005
#define int long long
std::mt19937 chaos(20071109);
int sum[_N_],val[_N_],siz[_N_],rnk[_N_],fa[_N_],lc[_N_],rc[_N_];
int new_FHQ(int now,int v){
now[siz]=1;
now[sum]=now[val]=v;
now[rnk]=chaos();
}
void update(int now){
now[sum]=now[lc][sum]+now[val]+now[rc][sum];
now[siz]=now[lc][siz]+1+now[rc][siz];
now[lc][fa]=now[rc][fa]=now;
}
void split(int now,int& L,int& R,int s){
if(!now)L=R=0;
else if(s<=now[lc][siz])
R=now,split(R[lc],L,R[lc],s),update(R);
else
L=now,split(L[rc],L[rc],R,s-now[lc][siz]-1),update(L);
}
int merge(int L,int R){
if(!L||!R)return L+R;
if(L[rnk]<R[rnk])
return L[rc]=merge(L[rc],R),update(L),L;
else
return R[lc]=merge(L,R[lc]),update(R),R;
}
int get_root(int now){
while(now[fa])now=now[fa];
return now;
}
int rank(int now){
int ret=now[lc][siz]+1;
while(now){
if(now==now[fa][rc])
ret+=now[fa][lc][siz]+1;
now=now[fa];
}
return ret;
}
void M(int x,int y){
x=get_root(x),y=get_root(y);
if(x!=y)merge(y,x);
}
void D(int x){
int root=get_root(x);
x=rank(x);
int L,R;
split(root,L,R,x-1);
L[fa]=R[fa]=0;
}
int Q(int x,int y){
int root_x=get_root(x),root_y=get_root(y);
if(root_x!=root_y)return -1;
int rnk_x=rank(x),rnk_y=rank(y);
if(rnk_x>rnk_y)std::swap(rnk_x,rnk_y);
int L,M,R;
split(root_x,L,R,rnk_y);
split(L,L,M,rnk_x-1);
int ret=M[sum];
merge(merge(L,M),R);
return ret;
}
signed main(){
int n,m;
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
int x;
scanf("%lld",&x);
new_FHQ(i,x);
}
while(m--){
static char op[5];
int x,y;
scanf("%s",op);
if(*op=='M'){
scanf("%lld%lld",&x,&y);
M(x,y);
}
if(*op=='D'){
scanf("%lld",&x);
D(x);
}
if(*op=='Q'){
scanf("%lld%lld",&x,&y);
printf("%lld\n",Q(x,y));
}
}
}
第三行#define _N_ 200005会全部RE,换成2000006就过了。是范围的问题吗