zoukankan      html  css  js  c++  java
  • 【2019.8.6 慈溪模拟赛 T2】树上路径(tree)(Trie)

    从暴力考虑转化题意

    考虑最暴力的做法,我们枚举路径的两端,然后采用类似求树上路径长度的做法,计算两点到根的贡献,然后除去(LCA)到根的贡献两次。

    即,设(v_i)(i)到根路径上的边权异或和,那么((x,y))的答案就是:

    [v_x xor v_y xor v_{LCA(x,y)} xor v_{LCA(x,y)} ]

    由于(v_{LCA(x,y)} xor v_{LCA(x,y)}=0),所以答案就是:

    [v_x xor v_y ]

    于是,题意就变成了,在若干个数中,找出异或值最大的两个数。

    (Trie)

    我们把每个(v_i)扔入(Trie)中,然后对于每个(v_i)(Trie)树上查询最大异或值(基础操作略)。

    这样就可以了。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 1000000
    #define add(x,y,v) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].val=v)
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n,ee,lnk[N+5];struct edge {int to,nxt,val;}e[N<<1];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
    }F;
    class TrieSolver
    {
    	private:
    		int v[N+5];
    		template<int SZ,int BIT> class Trie//Trie树
    		{
    			private:
    				int rt,Nt,V[SZ*BIT+5],S[SZ*BIT+5][2];
    				I void Ins(CI v,int& rt,CI d) {!rt&&(rt=++Nt),~d&&(Ins(v,S[rt][v>>d&1],d-1),0);}//插入
    				I int Qry(CI v,CI rt,CI d)//求最大异或值
    				{
    					if(!rt||!~d) return 0;RI t=v>>d&1;
    					return S[rt][t^1]?(Qry(v,S[rt][t^1],d-1)|(1<<d)):Qry(v,S[rt][t],d-1);//能取1就取1
    				}
    			public:
    				I void Ins(CI v) {Ins(v,rt,BIT);}
    				I int Qry(CI v) {return Qry(v,rt,BIT);}
    		};Trie<N,30> T;
    		I void dfs(CI x,CI lst=0)//dfs遍历
    		{
    			RI i;for(i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&
    				(v[e[i].to]=v[x]^e[i].val,dfs(e[i].to,x),0);T.Ins(v[x]);
    		}
    	public:
    		I void Solve()
    		{
    			RI i,t,ans=0;for(dfs(1),i=1;i<=n;++i) t=T.Qry(v[i]),Gmax(ans,t);//枚举v求答案
    			printf("%d",ans);//输出答案
    		}
    }S;
    int main()
    {
    	freopen("tree.in","r",stdin),freopen("tree.out","w",stdout);
    	RI i,x,y,z;for(F.read(n),i=1;i^n;++i) F.read(x),F.read(y),F.read(z),add(x,y,z),add(y,x,z);
    	return S.Solve(),0;
    }
    
  • 相关阅读:
    【Android】Handler的应用(二):从服务器端加载JSON数据的优化
    [置顶] IOS 开发之 CocoaPods讲解
    POJ 1068 (13.10.11)
    android使用百度地图、定位SDK实现地图和定位功能!(最新、可用+吐槽)
    C++笔记(1)
    WCF讲解
    php5 图片验证码一例
    PHP5 GD库生成图形验证码(汉字)
    mysql中limit的用法实例解析
    Limit参数优化MySQL查询的方法
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Contest20190806T2.html
Copyright © 2011-2022 走看看