BZOJ 1954 (POJ 3764) Trie的经典应用 求树上最大异或值
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1954 (然而这是权限题…… 所以还是看POJ 3764吧)
感谢黄学长。。涨姿势了。。
树上路径问题,xor运算满足分配率交换律,先求出每个节点到根节点的路径权值,这样就转化为从一堆值中选出两个xor起来最大的。
于是把这一堆值(不足30位的补到30位)一一插入一颗Trie中,然后一一查询每个值。每次查询,尽量走与当前查询值在该位不同的边,以获得xor值的最大。
最终的答案即为所有查询结果的最大值。
2016.1.13更新:啊啊啊刚刚开通了权限账号,立刻补番,结果。。BZOJ要不要这么坑!。。在HINT的一个不起眼的小角落里,“注意:结点下标从1开始到N....”。。导致WA了两次… 简直丧病。。
1 // BZOJ 1954 ( POJ 3764 ) 2 3 #include <cstdio> 4 #include <algorithm> 5 #include <cstring> 6 using namespace std; 7 8 const int N=100000+5, M=N; 9 10 struct Edge { 11 int from, to, w, pre; 12 }e[M*2]; 13 14 int k, last[N], ch[N*30][2], sz, n, u, v, w, ans, d[N]; 15 16 void ine(int x, int y, int w) { 17 k++; 18 e[k].from=x, e[k].to=y, e[k].pre=last[x], e[k].w=w; 19 last[x]=k; 20 } 21 #define reg(i,x) for (int i=last[x]; i; i=e[i].pre) 22 23 #define rep(i,a,b) for (int i=a; i<=b; i++) 24 #define dep(i,a,b) for (int i=a; i>=b; i--) 25 #define read(x) scanf("%d", &x) 26 #define fill(a,x) memset(a, x, sizeof(a)) 27 28 void change(int x, int fa, int dis) { 29 d[x]=dis; 30 reg(i,x) { 31 int y=e[i].to; 32 if (y==fa) continue; 33 change(y, x, dis^e[i].w); 34 } 35 } 36 37 void init() { k=0; fill(last, 0); fill(d, 0); sz=1; fill(ch, 0); } 38 39 void charen(int x, int *s) { 40 rep(i,0,30) s[i]=0; 41 int i=0; 42 while (x>0) s[i++]=(x%2), x/=2; 43 } 44 45 int s[35]; 46 void insert(int x) { 47 int u=1; 48 charen(x, s); 49 dep(i,30,0) { 50 if (!ch[u][s[i]]) { 51 sz++; 52 ch[sz][0]=ch[sz][1]=0; 53 ch[u][s[i]]=sz; 54 } 55 u=ch[u][s[i]]; 56 } 57 } 58 59 void search(int x) { 60 charen(x, s); 61 int u=1, t=0; 62 dep(i,30,0) 63 if (ch[u][s[i]^1]) { 64 t+=(1<<i); 65 u=ch[u][s[i]^1]; 66 } 67 else u=ch[u][s[i]]; 68 ans=max(ans, t); 69 } 70 71 int main() 72 { 73 while (scanf("%d", &n)==1 && n) { 74 init(); 75 rep(i,1,n-1) read(u),read(v),read(w),u++,v++,ine(u, v, w),ine(v, u, w); 76 // BZOJ上提交的话要把u++ v++去掉…… 77 78 change(1, 0, 0); 79 80 ans=0; 81 rep(i,1,n) insert(d[i]); 82 rep(i,1,n) search(d[i]); 83 84 printf("%d\n", ans); 85 } 86 87 return 0; 88 } 89