POJ 3764 The xor-longest( 树上异或前缀和&字典树求最大异或)
In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:
⊕ is the xor operator.
We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?
Input
The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.
Output
For each test case output the xor-length of the xor-longest path.
Sample Input
4 0 1 3 1 2 4 1 3 6
Sample Output
7
Hint
The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)
题意:
给出一棵树,求树上的最大路径异或和。
思路:
dfs得到根到节点的异或前缀和,然后把每个点的异或前缀和插入字典树中,就可以按套路,在字典树里找对应的最大异或了。
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int maxm=200010; const int maxn=3000000; int Laxt[maxm],Next[maxm],To[maxm],val[maxm],cnt,Xor[maxm];//dfs int ch[maxn][2],tot,ans,b[40],n;//trie int q_pow(int a,int x){ int res=1;while(x){if(x&1) res*=a;x>>=1;a*=a;} return res;} int read() { int res=0; char c=getchar(); for(;c>'9'||c<'0';c=getchar()); for(;c<='9'&&c>='0';res=res*10+c-'0',c=getchar()) ; return res; } void init() { memset(Laxt,0,sizeof(Laxt)); memset(Xor,0,sizeof(Xor)); memset(ch,0,sizeof(ch)); cnt=tot=ans=0; } void add(int u,int v,int x) { Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; val[cnt]=x; } void dfs(int u,int pre,int x) { for(int i=Laxt[u];i;i=Next[i]){ if(To[i]!=pre){ Xor[To[i]]=x^val[i]; dfs(To[i],u,Xor[To[i]]); } } } void insert(int x) { int Now=0; for(int i=0;i<=31;i++) { b[i]=x&1;x>>=1;} for(int i=31;i>=0;i--){ if(!ch[Now][b[i]]) ch[Now][b[i]]=++tot; Now=ch[Now][b[i]]; } } void find(int x) { int Now=0,tmp=0; for(int i=0;i<=31;i++){ b[i]=x&1; x>>=1; } for(int i=31;i>=0;i--){ if(ch[Now][b[i]^1]) Now=ch[Now][b[i]^1],tmp+=q_pow(2,i); else Now=ch[Now][b[i]]; } ans=max(ans,tmp); } void build() { for(int i=1;i<=n;i++) insert(Xor[i]); for(int i=1;i<=n;i++) find(Xor[i]); } int main() { while(~scanf("%d",&n)){ init(); int u,v,x; for(int i=1;i<n;i++){ u=read();v=read();x=read(); u++;v++; add(u,v,x); add(v,u,x); } dfs(1,0,0); build(); printf("%d\n",ans); } return 0; }
It is your time to fight!