传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6687
题解传送门:https://blog.csdn.net/liufengwei1/article/details/98536161
8说了,原题竟然没有人开,我看都没看。。。
claris还说第五场这题过了76个这场怎么就过了8个。。。
那题求最小,这题求最大,改改finda和findb函数中对字典树的路径选择就过了
#include<bits/stdc++.h>
#define maxl 100010
using namespace std;
int n,m,tota,totb,sum;
int ans[maxl],mi[30];
int a[maxl],b[maxl];
int suma[maxl*31],sumb[maxl*31];
int tra[maxl*31][2],trb[maxl*31][2];
int q[maxl],w[maxl];
vector <int> numa[maxl*31],numb[maxl*31];
vector <int> :: iterator it;
bool ina[maxl],inb[maxl];
inline void inserta(int id,int x)
{
int u=0,c;
for(int i=30;i>=0;i--)
{
suma[u]++;
c=(x>>i)&1;
if(!tra[u][c])
tra[u][c]=++tota;
u=tra[u][c];
}
suma[u]++;numa[u].push_back(id);
}
inline void insertb(int id,int x)
{
int u=0,c;
for(int i=30;i>=0;i--)
{
sumb[u]++;
c=(x>>i)&1;
if(!trb[u][c])
trb[u][c]=++totb;
u=trb[u][c];
}
sumb[u]++;numb[u].push_back(id);
}
inline void prework()
{
for(int i=0;i<=tota;i++)
{
tra[i][0]=tra[i][1]=0;
suma[i]=0;numa[i].clear();
}
for(int i=0;i<=totb;i++)
{
trb[i][0]=trb[i][1]=0;
sumb[i]=0,numb[i].clear();
}
scanf("%d",&n);
tota=0;totb=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
inserta(i,a[i]);ina[i]=true;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
insertb(i,b[i]);inb[i]=true;
}
}
inline int finda(int x)
{
int u=0,c,tmp=0;
for(int i=30;i>=0;i--)
{
c=(x>>i)&1;
if(tra[u][c^1])
u=tra[u][c^1];
else
u=tra[u][c];
}
it=numa[u].end();--it;
return (*it);
}
inline int findb(int x)
{
int u=0,c;
for(int i=30;i>=0;i--)
{
c=(x>>i)&1;
if(trb[u][c^1])
u=trb[u][c^1];
else
u=trb[u][c];
}
it=numb[u].end();--it;
return (*it);
}
inline void dela(int x)
{
int u=0,c,last;suma[u]--;
for(int i=30;i>=0;i--)
{
c=(x>>i)&1;last=u;
u=tra[u][c];
suma[u]--;
if(suma[u]==0)
tra[last][c]=0;
}
it=numa[u].end();--it;
numa[u].erase(it);
}
inline void delb(int x)
{
int u=0,c,last;sumb[u]--;
for(int i=30;i>=0;i--)
{
c=(x>>i)&1;last=u;
u=trb[u][c];
sumb[u]--;
if(sumb[u]==0)
trb[last][c]=0;
}
it=numb[u].end();--it;
numb[u].erase(it);
}
inline void dfs(int k)
{
int id;
if(k&1)
{
id=finda(b[q[k-1]]);
if(id==q[k-2] && k-2>0)
{
delb(b[q[k-1]]);
dela(a[id]);
inb[q[k-1]]=false;
ina[id]=false;
ans[++ans[0]]=b[q[k-1]]^a[id];
k-=2;sum--;
}
else
{
w[k]=b[q[k-1]]^a[id];
q[k]=id;k++;
}
if(sum>0)
dfs(k);
}
else
{
id=findb(a[q[k-1]]);
if(id==q[k-2] && k-2>0)
{
dela(a[q[k-1]]);
delb(b[id]);
ina[q[k-1]]=false;
inb[id]=false;
ans[++ans[0]]=a[q[k-1]]^b[id];
k-=2;sum--;
}
else
{
w[k]=a[q[k-1]]^b[id];
q[k]=id;k++;
}
if(sum>0)
dfs(k);
}
}
inline void mainwork()
{
ans[0]=0;sum=n;
for(int i=1;i<=n;i++)
if(ina[i])
{
q[1]=i;
dfs(2);
}
}
inline void print()
{
long long sum=0;
for(int i=1;i<=n;i++)
sum+=ans[i];
printf("%lld\n",sum);
}
int main()
{
mi[0]=1;
for(int i=1;i<=30;i++)
mi[i]=mi[i-1]*2;
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}