【POJ3764】The xor-longest Path Trie树+异或性质

#include <stdio.h>
int main()
{
	puts("转载请注明出处[vmurder]谢谢");
	puts("网址:blog.csdn.net/vmurder/article/details/43486733");
}

题意:

多组数据、

给你一颗树,

然后求一条最长异或路径,

异或路径长度定义为两点间简单路径上所有边权的异或和。

题解:

首先无根树转有根树再在树上跑一遍算出每个点到根的异或和。

然后两点间异或路径长度就是a[i]*a[j]。

因为lca之前那一段都被异或了两次搞没了。

然后求个线性基,然后随便搞搞就可以?可以WA了!

因为那么算哪是简单路径啊,或者说,那特喵的是什么玩意啊。

嗯,写个Trie树,然后详情可以看我这篇博客。

【JDFZOJ】最富有的人
Trie树+异或性质

诶?这篇博客什么也没说?

好吧,我补个题解:

Trie里面记录每个节点权值的二进制串,

比如5,我们不记录“101”,而是记录“00000……000101”

这样Trie树建好了以后我们枚举一个节点,然后用这个节点在Trie树中找它的最长异或路径长度。

这个时候我们在Trie树上跑,每一位都取反以保证这位尽量是1

然后走不了再取同。

所有最长中取个最大值作为答案

这样就在nlogn时间内得到了解。

详见代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
#define LOGN 32
#define T 2
#define inf 0x3f3f3f3f
using namespace std;
int src[N],n;
struct Trie
{
	int son[N*LOGN][T],cnt;
	void init()
	{
		memset(son,0,sizeof son);
		cnt=0;
	}
	void insert(int a)
	{
		int i,x=0,alp;
		for(i=31;i>=0;i--)
		{
			alp=(a>>i)&1;
			if(!son[x][alp])son[x][alp]=++cnt;
			x=son[x][alp];
		}
	}
	int find(int a)
	{
		int i,x=0,alp;
		int ret=0;
		for(i=31;i>=0;i--)
		{
			alp=!((a>>i)&1);
			ret<<=1;
			if(son[x][alp])
			{
				x=son[x][alp];
				ret++;
			}
			else x=son[x][!alp];
		}
		return ret;
	}
}trie;
struct KSD
{
	int v,len,next;
}e[N<<1];
int head[N],cnt;
void init()
{
	cnt=0;
	memset(src,0,sizeof src);
	memset(head,0,sizeof head);
	trie.init();
}
inline void add(int u,int v,int len)
{
	e[++cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void dfs(int x,int p)
{
	int i,v;
	for(i=head[x];i;i=e[i].next)
	{
		v=e[i].v;
		if(v==p)continue;
		src[v]=src[x]^e[i].len;
		dfs(v,x);
	}
	return ;
}
int main()
{
	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;

	while(scanf("%d",&n)!=EOF)
	{
		init();
		for(i=1;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			add(a+1,b+1,c),add(b+1,a+1,c);
		}
		dfs(1,0);
		int ans=0;
		for(i=1;i<=n;i++)trie.insert(src[i]);
		for(i=1;i<=n;i++)ans=max(ans,trie.find(src[i]));
		printf("%d\n",ans);
	}

	return 0;
}
时间: 2024-11-05 11:27:01

【POJ3764】The xor-longest Path Trie树+异或性质的相关文章

poj3764 The XOR Longest Path【dfs】【Trie树】

The xor-longest Path Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10038   Accepted: 2040 Description In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p: ⊕ is the xor operator. W

【JDFZOJ】最富有的人 Trie树+异或性质

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43446799"); } 题面: 最富有的人 Time Limit: 1 Sec  Memory Limit: 64 MB Description 你经过了一段时间的打工,老板带你来到了他的私人金库. 在你的面前有n堆金子,老板要求你只能选择其中的两堆

HDU 5269 ZYB loves Xor I( 01 Trie 树)

题目链接:传送门 题意: 求 for i: 1~n  forj:1~n lowbit(a[i]^a[j]) lowbit(x)表示取x的最低位1. lowbit(3)=1    lowbit(6)=2; 分析: 因为其中有一个异或运算,我们就先来分析这个异或运算.发现如果lowbit(x^y) = 2^p; 那么把x^y转化成2进制后他们的前p-1位一定是相同的.那么思路就来了把所有的数字转换 成01字符串,注意要使他们的长度都相等,然后建一颗trie树.然后遍历的时候如果同时 有左右孩子的话那

HDU4825 Xor Sum(贪心+Trie树)

今天本来想写一个可持久化Trie树,发现这道题一直没做就补上了. 其实思路很简单,假如说两个数,和同一个数异或,很显然,由于进制,高位上的一个1可以大于低位上所有1,所以即使后面的情况再糟糕,也比取后面好的值高(其实就是1000比0111大) 所以可以建一个01线段树,从高往低插入一个数,比较时取反即可^_^ 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace st

HDU 4825 Trie树 异或树!

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 2403    Accepted Submission(s): 1041 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

Trie树(字典树)(1)

Trie树.又称字典树,单词查找树或者前缀树,是一种用于高速检索的多叉树结构. Trie树与二叉搜索树不同,键不是直接保存在节点中,而是由节点在树中的位置决定. 一个节点的全部子孙都有同样的前缀(prefix),也就是这个节点相应的字符串,而根节点相应空字符串.普通情况下.不是全部的节点都有相应的值,仅仅有叶子节点和部分内部节点所相应的键才有相关的值. A trie, pronounced "try", is a tree that exploits some structure in

Trie树的C++实现

先给出LintCode的题目:实现Trie树 Trie树就是字典树,用在搜索引擎如百度搜索词条,还比如说之前DNS域名解析系统搜索根据域名搜索IP.总之,是棵树,根据字符串搜索某一节点,同时就可获得节点存储的信息了. Trie树的一般性质如下: 1.根节点不包含字符,除根节点外每一个节点都只包含一个字符. 2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串. 3.每个节点的所有子节点包含的字符都不相同. 那么既然是树,既然需要和字符串匹配,那么树的节点怎么定义?我们可以这样分

数据结构之Trie树

1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tri:/ "tree",也有人读为/tra?/ "try". Trie树可以利用字符串的公共前缀来节约存储空间.如下图所示,该trie树用10个节点保存了6个字符串tea,ten,to,in,inn,int: 在该trie树中,字符串in,inn和int的公共前缀是&qu

Trie树详解

1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.Trie一词来自retrieve,发音为/tri:/ “tree”,也有人读为/tra?/ “try”.Trie树可以利用字符串的公共前缀来节约存储空间.如下图所示,该trie树用10个节点保存了6个字符串tea,ten,to,in,inn,int: 在该trie树中,字符串in,inn和int的公共前缀是“in”,因此可以只存储一份“in”以节