全部re,蒟蒻求助
查看原帖
全部re,蒟蒻求助
362627
frank15楼主2021/2/17 21:36
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=8e4+5;
int testcase,n,m,T,tot,pos,cnt,x,y,k,size_x,size_y,fx,fy,lastans,lca; 
int lg[maxn],discre[maxn],root[maxn];
char c;
vector<int> v[maxn];
struct miku{
	int num,depth,father[20],fa,sum;
}a[maxn];
struct t{
	int lson,rson,sum;
}tree[maxn<<10];
//2¢2é?ˉ
int find(int k){
	if(a[k].fa==k)
		return k;
	return a[k].fa=find(a[k].fa);
} 
//lca
void dfs(int node,int FA){
	a[node].father[0]=FA;
	a[node].depth=a[FA].depth+1;
	for(int i=1;i<=lg[a[node].depth];i++)
		a[node].father[i]=a[a[node].father[i-1]].father[i-1];
	for(int i=0;i<v[node].size();i++)
		if(v[node][i]!=FA)
			dfs(v[node][i],node);
	return ;
}
int LCA(int u,int v){
	if(a[u].depth<a[v].depth)
		swap(u,v);
	while(a[u].depth>a[v].depth)
		u=a[u].father[lg[a[u].depth-a[v].depth]-1];
	if(u==v)
		return u	;
	for(int i=lg[a[u].depth]-1;i>=0;i--){
		if(a[u].father[i]!=a[v].father[i]){
			u=a[u].father[i];
			v=a[v].father[i];
		}
	}
	return a[u].father[0];
}
//????ê÷ 
int build(int l,int r){
	int node=++cnt;
	int mid=(l+r)>>1;
	if(l<r){
		build(l,mid);
		build(mid+1,r);
	}
	return node;
}
int update(int node1,int node2,int l,int r,int aim){
	if(!node1)
		node1=++cnt;
	tree[node1].sum=tree[node2].sum+1;
	tree[node1].lson=tree[node2].lson;
	tree[node1].rson=tree[node2].rson;
	if(l<r){
		int mid=(l+r)>>1;
		if(aim<=mid)
			tree[node1].lson=update(tree[node1].lson,tree[node2].lson,l,mid,aim);
		else
			tree[node1].rson=update(tree[node1].rson,tree[node2].rson,mid+1,r,aim);
	}
	return node1;
}
int merge(int node1,int node2,int l,int r){
	if(!node1)
		return node2;
	if(!node2)
		return node1;
	if(l==r){
		tree[node1].sum+=tree[node2].sum;
		return node1;
	}
	int mid=(l+r)>>1;
	if(l<r){
		tree[node1].lson=merge(tree[node1].lson,tree[node2].lson,l,mid);
		tree[node1].rson=merge(tree[node1].rson,tree[node2].rson,mid+1,r);
		tree[node1].sum=tree[tree[node1].lson].sum+tree[tree[node1].rson].sum;
	}
	return node1;
}
void change(int node,int FA){
	for(int i=0;i<v[node].size();i++)
		if(v[node][i]!=FA){
			root[v[node][i]]=update(root[v[node][i]],root[node],1,tot,a[v[node][i]].num);
			change(v[node][i],node);
		}
	return ;
}
int query(int node1,int node2,int node3,int node4,int l,int r,int k){
	if(l==r)
		return l;
	int mid=(l+r)>>1;
	int SUM=tree[tree[node3].lson].sum+tree[tree[node4].lson].sum-tree[tree[node1].lson].sum-tree[tree[node2].lson].sum;
//	cout<<SUM<<endl;
	if(SUM>=k)
		return query(tree[node1].lson,tree[node2].lson,tree[node3].lson,tree[node4].lson,l,mid,k);
	else
		return query(tree[node1].rson,tree[node2].rson,tree[node3].rson,tree[node4].rson,mid+1,r,k-SUM);
}
void print(int node,int l,int r){
	printf("%d %d %d\n",l,r,tree[node].sum);
	int mid=(l+r)>>1;
	if(l<r){
	print(tree[node].lson,l,mid);
	print(tree[node].rson,mid+1,r);
	}
}
int main(){
	scanf("%d",&testcase);
	scanf("%d%d%d",&n,&m,&T);
	for(int i=1;i<=n;i++)
		lg[i]=int(log2(i))+1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i].num);
		dfs(i,0);
		a[i].fa=i;
		a[i].sum=1;
		discre[i]=a[i].num;
	}
	sort(discre+1,discre+n+1);
	tot=unique(discre+1,discre+n+1)-(discre+1);
	root[0]=build(1,tot);
	for(int i=1;i<=n;i++){
		pos=lower_bound(discre+1,discre+tot+1,a[i].num)-discre;
		root[i]=update(root[i],root[0],1,tot,pos);
//		print(root[i],1,tot);
//		cout<<endl;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
//		cout<<endl;
		v[x].push_back(y);
		v[y].push_back(x);
		fx=find(a[x].fa);
		fy=find(a[y].fa);
		size_x=a[fx].sum;
		size_y=a[fy].sum;
		if(size_x<size_y){
			a[fy].sum+=a[fx].sum;
			a[fx].sum=0;
			a[fx].fa=fy;
			dfs(fx,y);
//			print(root[y],1,tot);
//			cout<<endl;
			root[fx]=merge(root[fx],root[y],1,tot);
//			printf("%d %d\n",fx,y);
//			print(root[fx],1,tot);
//			cout<<endl;
//			print(root[y],1,tot);
//			cout<<endl;
			change(fx,a[fx].father[0]);
		}
		else{
			a[fx].sum+=a[fy].sum;
			a[fy].sum=0;
			a[fy].fa=fx;
			dfs(fy,x);
//			print(root[fy],1,tot);
//			cout<<endl;
			root[fy]=merge(root[fy],root[x],1,tot);
//			printf("%d %d\n",fy,x);
//			print(root[fy],1,tot);
//			cout<<endl;
//			print(root[x],1,tot);
//			cout<<endl;
			change(fy,a[fy].father[0]);
		}
	}
//	for(int i=1;i<=n;i++)
//		cout<<a[i].fa<<' ';
//	cout<<endl;
//	for(int i=1;i<=n;i++){
//		print(root[i],1,tot);
//		cout<<endl;		
//	}
	while(T--){
		cin>>c;
		if(c=='Q'){
			scanf("%d%d%d",&x,&y,&k);
			x=x^lastans;
			y=y^lastans;
			k=k^lastans;
//			cout<<x<<' '<<y<<' '<<k<<endl;
			lca=LCA(x,y);
//			cout<<lca<<endl;
			lastans=discre[query(root[lca],root[a[lca].father[0]],root[x],root[y],1,tot,k)];
			printf("%d\n",lastans);
		}
		else{
			scanf("%d%d",&x,&y);
			x=x^lastans;
			y=y^lastans;
//			cout<<x<<' '<<y<<endl;
			v[x].push_back(y);
			v[y].push_back(x);
			fx=find(a[x].fa);
			fy=find(a[y].fa);
			size_x=a[fx].sum;
			size_y=a[fy].sum;
//			cout<<fx<<' '<<fy<<endl;
			if(size_x<size_y){
				a[fy].sum+=a[fx].sum;
				a[fx].sum=0;
				a[fx].fa=fy;
				dfs(fx,y);
//				print(root[y],1,tot);
//				cout<<endl;
				root[fx]=merge(root[fx],root[y],1,tot);
//				printf("%d %d\n",fx,y);
//				print(root[fx],1,tot);
//				cout<<endl;
//				print(root[y],1,tot);
//				cout<<endl;
				change(fx,a[fx].father[0]);
			}
			else{
				a[fx].sum+=a[fy].sum;
				a[fy].sum=0;
				a[fy].fa=fx;
				dfs(fy,x);
//				print(root[fy],1,tot);
//				cout<<endl;
				root[fy]=merge(root[fy],root[x],1,tot);
//				printf("%d %d\n",fy,x);
//				print(root[fy],1,tot);
//				cout<<endl;
//				print(root[x],1,tot);
//				cout<<endl;
				change(fy,a[fy].father[0]);
			}
		}
	}
	return 0;
} 
2021/2/17 21:36
加载中...