three arrays(hdu多校联测round5)

题目链接

对A和B分别建两棵trie树, 两边同时找, 尽量找相同的, 找到叶子节点时记录答案, 最后将答案排序输出.

#include<bits/stdc++.h>
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}
const int N=3.5e6+28;
struct TRIE{
    int ch[N][2],sum[N],val[N],tot;
    int Ins(int x){
	int p=1;
	for(int i=31;i>=0;i--){
	    int v=((x&(1<<i))!=0);
	    if(!ch[p][v])ch[p][v]=++tot;
	    p=ch[p][v];
	}
	sum[p]++;
	val[p]=x;
    }
    void Updata(int p){
	sum[p]=sum[ch[p][0]]+sum[ch[p][1]];
	if(sum[ch[p][0]]<=0)ch[p][0]=0;
	if(sum[ch[p][1]]<=0)ch[p][1]=0;
    }
    void Dfs(int p=1){
	if(val[p]!=-1)return;
	if(ch[p][0])Dfs(ch[p][0]);
	if(ch[p][1])Dfs(ch[p][1]);
	Updata(p);
    }
    void format(){
	for(int i=0;i<=tot;i++){
	    sum[i]=0;
	    val[i]=-1;
	    ch[i][0]=ch[i][1]=0;
	}
	tot=1;
    }
    stack<int>stk;
    int Query(int x){
	int p=1;
	stk.push(p);
	for(int i=31;i>=0;i--){
	    int v=((x&(1<<i))!=0);
	    if(ch[p][v])p=ch[p][v];
	    else p=ch[p][v^1];
	    stk.push(p);
	}
	stk.pop();
	sum[p]--;
	while(stk.size())Updata(stk.top()),stk.pop();
	//printf("%d^%d=%d sum=%d\n",val[p],x,val[p]^x,sum[p]);
	return val[p]^x;
    }
    TRIE(){
	memset(sum,0,sizeof(sum));
	memset(val,-1,sizeof(val));
	memset(ch,0,sizeof(ch));
	tot=1;
    }
}A,B;
int ans[N],cnt;
void format(){
    A.format();
    B.format();
    cnt=0;
}
void dfs(int pa=1,int pb=1){
    if(A.val[pa]!=-1){
	ans[++cnt]=A.val[pa]^B.val[pb];
	A.sum[pa]--,B.sum[pb]--;
	return;
    }
    while(A.ch[pa][0]&&B.ch[pb][0]){
	dfs(A.ch[pa][0],B.ch[pb][0]);
	A.Updata(pa),B.Updata(pb);
    }
    while(A.ch[pa][1]&&B.ch[pb][1]){
	dfs(A.ch[pa][1],B.ch[pb][1]);
	A.Updata(pa),B.Updata(pb);
    }
    while(A.ch[pa][0]&&B.ch[pb][1]){
	dfs(A.ch[pa][0],B.ch[pb][1]);
	A.Updata(pa),B.Updata(pb);
    }
    while(A.ch[pa][1]&&B.ch[pb][0]){
	dfs(A.ch[pa][1],B.ch[pb][0]);
	A.Updata(pa),B.Updata(pb);
    }
}
signed main(){
    int t=read();
    while(t--){
	format();
	int n=read();
	for(int i=1;i<=n;i++){
	    int a=read();
	    A.Ins(a);
	}
	A.Dfs();
	for(int i=1;i<=n;i++){
	    int b=read();
	    B.Ins(b);
	}
	B.Dfs();
	dfs();
	sort(ans+1,ans+n+1);
	for(int i=1;i<=n;i++){
	    printf("%d",ans[i]);
	    if(i!=n)putchar(' ');
	}
	puts("");
    }
    return 0;
}
posted @ 2019-08-05 21:51  The_KOG  阅读(176)  评论(0编辑  收藏  举报