把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【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;
}
posted @ 2019-08-07 17:39  TheLostWeak  阅读(180)  评论(0编辑  收藏  举报