BZOJ 1954: Pku3764 The xor-longest Path(贪心+trie)

传送门

解题思路

  \(trie\)的一个比较经典的应用,首先把每个点到根的异或和算出,然后建一棵\(trie\)把所有权值插入到\(Trie\)中,之后枚举所有结点,在\(Trie\)上贪心的跑统计答案,时间复杂度\(O(nlogn)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int N=100005;

inline int rd(){
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return f?x:-x;	
}

int n,head[N],cnt,to[N<<1],nxt[N<<1],val[N<<1];
int tot,ans,res,w[N],rt;

struct Trie{
	int ch[N*40][2];
	void insert(int &x,int d,int now){
		if(!x) x=++tot; if(!d) return;
		if((1<<(d-1))&now) insert(ch[x][1],d-1,now);
		else insert(ch[x][0],d-1,now);	
	}
	void query(int x,int d,int now){
		if(!d) return;
		if((1<<(d-1))&now) {
			if(ch[x][0]) res|=(1<<(d-1)),query(ch[x][0],d-1,now);
			else query(ch[x][1],d-1,now);	
		}
		else {
			if(ch[x][1]) res|=(1<<(d-1)),query(ch[x][1],d-1,now);
			else query(ch[x][0],d-1,now);	
		}
	}
}tree;

inline void add(int bg,int ed,int w){
	to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;	
}

void dfs(int x,int F){
	for(int i=head[x];i;i=nxt[i]){
		int u=to[i]; if(u==F) continue;
		w[to[i]]=(w[x]^val[i]); dfs(u,x);
	}
}

int main(){
	n=rd(); int x,y,z;
	for(int i=1;i<n;i++){
		x=rd(),y=rd(),z=rd();
		add(x,y,z),add(y,x,z);	
	}
	dfs(1,0);
	for(int i=1;i<=n;i++) tree.insert(rt,31,w[i]);
	for(int i=1;i<=n;i++) 
		res=0,tree.query(rt,31,w[i]),ans=max(ans,res);
	printf("%d\n",ans);
	return 0;	
}
posted @ 2019-02-10 20:57  Monster_Qi  阅读(119)  评论(0编辑  收藏  举报