求 Hack
查看原帖
求 Hack
289296
zymooll楼主2023/5/5 11:38

在合并过程中直接将被合并树的根更改为合并的树的根也能够通过此题,但理论来说是不行的,故求问.

参考代码(待Hack):

// Author:zymooll

#include<bits/stdc++.h>
#define getchar getchar_unlocked
#define putchar putchar_unlocked
//#define int long long
using namespace std;
int read(){
	int s=0,w=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')w=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		s=s*10+c-'0';
		c=getchar();
	}
	return s*w;
}
void print(int x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>=10)print(x/10);
	putchar(x%10+'0');
	return;
}
int m,n,q;
int dmap[100010];
const int w=16;
struct Node{
    int son[2],cnt;
}t[2000010];
int ncnt=1;
vector<int>rub;
int newnode(){
    if(rub.empty()){
        return ++ncnt;
    }
    else{
        int ls=rub[rub.size()-1];
        rub.pop_back();
        t[ls].son[0]=t[ls].son[1]=t[ls].cnt=0;
        return ls;
    }
}
int root[100010];
int fa[100010];
void init(){
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
}
int find(int x){
    if(fa[x]!=x)fa[x]=find(fa[x]);
    return fa[x];
}
void mergefa(int x,int y){
    //x<-y
    fa[find(y)]=find(x);
}
void add(int u,int x){
    t[u].cnt++;
    for(int i=w;i>=0;i--){
        int c=(x>>i)&1;
        if(!t[u].son[c])t[u].son[c]=newnode();
        u=t[u].son[c];
        t[u].cnt++;
    }
}
void dfs(int u,int v,int sd,int num){
    if(sd==0){
        add(u,num);
        return;
    }
    if(t[v].son[0])dfs(u,t[v].son[0],sd-1,num);
    if(t[v].son[1])dfs(u,t[v].son[1],sd-1,num^(1<<(sd-1)));
    rub.push_back(v);
}
void merge(int u,int v){//u<-v
    if(t[root[u]].cnt<t[root[v]].cnt)swap(u,v);
    dfs(root[u],root[v],w+1,0);
    //root[v]=root[u];
    mergefa(u,v);
    /*
    此处,若直接使用
    root[v]=root[u]
    也能通过此题
    */
}
int kth(int u,int x){
    int ans=0;
    for(int i=w;i>=0;i--){
        if(x<=t[t[u].son[0]].cnt){
            u=t[u].son[0];
        }
        else{
            ans^=(1<<i);
            x-=t[t[u].son[0]].cnt;
            u=t[u].son[1];
        }
    }
    return ans==((2<<w)-1)?0:ans;
}
signed main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	n=read();m=read();
    init();
    dmap[0]=-1;
    for(int i=1;i<=n;i++){
        int ls=read();
        dmap[ls]=i;
        root[i]=newnode();
        add(root[i],ls);
    }
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        int fu=find(u),fv=find(v);
        merge(fu,fv);
    }
    q=read();
    for(int i=1;i<=q;i++){
        char opt=getchar();
        int x=read(),y=read();
        if(opt=='Q'){
            int fx=find(x);
            print(dmap[kth(root[fx],y)]);
            putchar('\n');
        }
        else{
            int fx=find(x),fy=find(y);
            merge(fx,fy);
        }
    }
	return 0;
}

2023/5/5 11:38
加载中...