1 条题解
-
0
另一道字典树的趣题。
模拟一下算路径上异或和的过程,我们发现对于两个节点 和 , 到 路径上的异或和 到根节点路径的异或和 到根节点的异或和 ,这就转化成了 「一本通 2.3 练习 5」The Xor-longest Path - HydroOJ 原题,我们求的就是 (任意两条到根节点的路径的异或和的) 异或最大值。
#include<bits/stdc++.h> using namespace std; #define N 100005 #define S 3200005 #define M 200005 int ch[S][2],n,a[N],tot,ans,cnt; int fir[N],to[M],nxt[M],w[M],xorx[N]; void add(int x,int y,int z){ nxt[++cnt]=fir[x]; fir[x]=cnt; to[cnt]=y; w[cnt]=z; } void write(int x){ if(x>=2)write(x>>1); putchar((x&1)+'0'); } void insert(int num,int x=0){ for(int i=1;i<=31;++i){ short c=((num&0x40000000)>>30); if(ch[x][c]==0)ch[x][c]=++tot; x=ch[x][c]; num<<=1; } } int search(int num,int x=0,int ret=0){ for(int i=1;i<=31;++i){ short c=1-((num&0x40000000)>>30); if(ch[x][c]==0){ ret<<=1; c=1-c; }else ret=((ret<<1)|1); x=ch[x][c]; num<<=1; } return ret; } void dfs(int x,int fa){ for(int e=fir[x];e;e=nxt[e]){ int u=to[e]; if(u==fa)continue; xorx[u]=xorx[x]^w[e]; dfs(u,x); } } int main(){ int x,y,z; scanf("%d",&n); for(int i=1;i<n;++i){ scanf("%d %d %d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs(1,0); for(int i=1;i<=n;++i){ // printf("x[%d]=%d\n",i,xorx[i]); insert(xorx[i]); } for(int i=1;i<=n;++i){ ans=max(ans,search(xorx[i])); } printf("%d",ans); return 0; }
- 1
信息
- ID
- 467
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 2
- 已通过
- 1
- 上传者