## fjwc2019 D6T2 密文（trie+贪心）

#194. 「2019冬令营提高组」密文

```#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int min(int a,int b){return a<b?a:b;}
#define N 100005
#define M 3000005
int n,t,rt,u,a[N],ch[M][2],le[M],ri[M],h[N];
long long ans;
void ins(int &x,int d,int i){
if(!x) x=++u;
if(i>=0) ins(ch[x][(d>>i)&1],d,i-1);
}
int find(int x,int d,int i){
if(i<0) return 0;
int p=(d>>i)&1;
return ch[x][p]?find(ch[x][p],d,i-1):find(ch[x][p^1],d,i-1)+(1<<i);
}
void dfs(int x,int d,int i){
if(i<0){
h[++t]=d; le[x]=ri[x]=t;
return;
}le[x]=t+1;
int lc=ch[x][0],rc=ch[x][1],L,R,mn=1<<i;
if(lc) dfs(lc,d,i-1);
if(rc) dfs(rc,d|(1<<i),i-1);
if(lc&&rc){
if(ri[lc]-le[lc]<ri[rc]-le[rc]) L=lc,R=rc;
else L=rc,R=lc;
for(int j=le[L];j<=ri[L];++j)
mn=min(mn,find(R,h[j],i-1));
ans+=mn+(1<<i);
}ri[x]=t;
}

int main(){
freopen("secret.in","r",stdin);
freopen("secret.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]),a[i]^=a[i-1];
for(int i=0;i<=n;++i) ins(rt,a[i],30);
dfs(rt,0,30); printf("%lld",ans);
return 0;
}```

0条评论