数据范围有假?
查看原帖
数据范围有假?
342185
__builtin_orz楼主2024/11/26 20:36

这是我的代码:

#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就过了。是范围的问题吗

2024/11/26 20:36
加载中...