• 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
    ",ans);
    	return 0;	
    }
    
  • 相关阅读:
    布局管理器
    下拉列表框
    时间,日期选择器
    关于部分基本控件的使用
    关于Activity
    什么时候修改class
    JavaScript Break 和 Continue 语句
    JavaScript While 循环
    JavaScript For 循环
    JavaScript Switch 语句
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10360243.html
Copyright © 2020-2023  润新知