【题目大意】给定一棵树,然后一条树的路径的权和定义为路径上边权全部xor之后得出的值
【算法分析】树的话。设d[x]为从根到x这条路径的权。那么两点间的路径权就是d[x] xor d[y]。(LCA到根部分被两次xor抵消啦),然后就转化为给定n个数,求d[x]^d[y]最大。这个就和USACO第6章那个cowxor一模一样啦。利用Trie树求解。
【时间复杂度】O(30*N)
【空间复杂度】O(30*N)
【其它】1Y。在lcc大神空间看到有这题,然后一看题目。。。Orz,再次见面的题目就成水题啦。。。睡前一水。
【CODE】
#include #include #include const int N=100005; struct edge{int y,w;edge *next;}g[N*2],*ls[N]; int n,e,tot; int d[N],L[N],v[N],ch[N*32][2]; void addedge(int x,int y,int w){ g[++e].y=y; g[e].w=w; g[e].next=ls[x]; ls[x]=&g[e]; g[++e].y=x; g[e].w=w; g[e].next=ls[y]; ls[y]=&g[e]; } void init(){ int i,x,y,w; for (e=i=0;i for (i=1;i scanf("%d%d%d",&x,&y,&w); addedge(x,y,w); } } void bfs(){ int i,head=-1,tail=0; for (i=0;i v[0]=1; L[0]=d[0]=0; while (head!=tail){ head++; for (edge *t=ls[L[head]];t;t=t->next) if (!v[t->y]){ d[t->y]=d[L[head]]^t->w; v[t->y]=1; L[++tail]=t->y; } } } void Insert(int x){ int s,p,t; for (p=1,s=30;s>=0;s--){ t=( (1< if (!ch[p][t]){ ch[p][t]=++tot; ch[tot][0]=ch[tot][1]=0; } p=ch[p][t]; } } int Get(int x){ int res=0,s,p,t; for (p=1,s=30;s>=0;s--){ t=( (1< if (ch[p][!t]) {p=ch[p][!t]; res|=!t< else {p=ch[p][t]; res|= t< } return res^x; } void work(){ tot=1; ch[1][0]=ch[1][1]=0; Insert(d[0]); int i,ans=0,now; for (i=1;i now=Get(d[i]); if (now>ans) ans=now; Insert(d[i]); } printf("%dn",ans); } int main(){ while (scanf("%d",&n)!=EOF){ init(); bfs(); work(); } }
牛得不像话……