题目描述

给定一棵 n 个点的带权树,结点下标从 1 开始到 N 。寻找树中找两个结点,求最长的异或路径。

异或路径指的是指两个结点之间唯一路径上的所有边权的异或。


输入输出格式

输入格式:

第一行一个整数 N ,表示点数。

接下来 n-1n−1 行,给出 u,v,w ,分别表示树上的 u 点和 v 点有连边,边的权值是 w 。




输出格式:

一行,一个整数表示答案。


输入输出样例

输入样例#1:

4

1 2 3

2 3 4

2 4 6

输出样例#1:

7


说明

最长异或序列是1-2-3,答案是 7 (=3 ⊕ 4)


数据范围

1≤n≤100000; 0<u,v≤n; 0≤w<2^31


Solution

这道题,套路题啊...

首先要考虑到两个思路:

1.异或的基本性质:

\[{({x}\bigoplus{y})}\bigoplus{y}=x
\]

2.带修改的01字典树

考虑枚举每一个点对,但是数据范围太大。

此时我们可以使用01字典树,步骤如下:

  • 先将边权转化为点权,预先处理出从根节点到每一个点的异或前缀和。
  • 然后将所有点的异或前缀和插入字典树中。
  • 再进行查询,注意查询时要将查询的点暂时删除。
  • 查询最大值即为答案。


代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=200008;
int ch[32*maxn][2];
ll val[32*maxn],c[maxn];
int num[32*maxn];
int sz,n;
ll b[maxn]; void insert(ll a)
{
int u=0;
for(int i=32;i>=0;i--)
{
int c=((a>>i)&1);
if(!ch[u][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
num[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
num[u]++;
}
val[u]=a;
} void update(ll a,int d)
{
int u=0;
for(int i=32;i>=0;i--)
{
int c=((a>>i)&1);
u=ch[u][c];
num[u]+=d;
}
} ll query(ll x)
{
int u=0;
for(int i=32;i>=0;i--)
{
int c=((x>>i)&1);
if(ch[u][c^1]&&num[ch[u][c^1]])
u=ch[u][c^1];
else u=ch[u][c];
}
return x^val[u];
} struct sj{
int to;
int next;
int w;
}a[maxn];
int size,head[maxn]; void add(int x,int y,int z)
{
a[++size].to=y;
a[size].w=z;
a[size].next=head[x];
head[x]=size;
} int v[maxn],now,ans=-1;
void dfs(int x)
{
v[x]=1;
c[x]=now;
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!v[tt])
{
now^=a[i].w;
dfs(tt);
now^=a[i].w;
}
}
} int main()
{
cin>>n;
for(int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dfs(1);
for(int i=1;i<=n;i++)
insert(c[i]);
for(int i=1;i<=n;i++)
{
update(c[i],-1);
int kk=query(c[i]);
ans=max(ans,kk);
update(c[i],1);
}
cout<<ans<<endl;
}

P4551 最长异或路径 (01字典树,异或前缀和)的更多相关文章

  1. hdu 4825 && acdream 1063 01字典树异或问题

    题意: 给一个集合,多次询问,每次给一个k,问你集合和k异或结果最大的哪个 题解: 经典的01字典树问题,学习一哈. 把一个数字看成32位的01串,然后查找异或的时候不断的沿着^为1的路向下走即可 # ...

  2. [BZOJ4260] Codechef REBXOR (01字典树,异或前缀和)

    Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,-,AN. Output 输出一行包含给定表达式可能的最大值. Sample ...

  3. AcWing 143. 最大异或对 01字典树打卡

    在给定的N个整数A1,A2……ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N. 第二行输入N个整数A1A1-ANAN. 输出格式 输出一 ...

  4. AcWing 144. 最长异或值路径 01字典树打卡

    给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n, ...

  5. BZOJ 4260 Codechef REBXOR (区间异或和最值) (01字典树+DP)

    <题目链接> 题目大意:给定一个序列,现在求出两段不相交的区间异或和的最大值. 解题分析: 区间异或问题首先想到01字典树.利用前缀.后缀建树,并且利用异或的性质,相同的两个数异或变成0, ...

  6. 数据结构&字符串:01字典树

    利用01字典树查询最大异或值 01字典树的是只含有0和1两种字符的字典树,在使用它的时候,把若干数字转成二进制后插入其中 在查询树中的哪个数字和给定数字有最大异或值的时候,从根开始贪心查询就ok了 H ...

  7. AcWing:144. 最长异或值路径(dfs + 01字典树)

    给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n, ...

  8. Codeforces 979 D. Kuro and GCD and XOR and SUM(异或和,01字典树)

    Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u ...

  9. Chip Factory---hdu5536(异或值最大,01字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:有一个数组a[], 包含n个数,从n个数中找到三个数使得 (a[i]+a[j])⊕a[k] ...

随机推荐

  1. 2018.4.12 各个系统安装MyEclipse过程(包括Mac、Linux、Windows)

    首先下载MyEclipse 最新官网在这里http://www.myeclipsecn.com/ mac 安装 . 在安装第一步会显示 "安装myeclipse显示更低版本javase6&q ...

  2. 使用mfc CHtmlView内存泄露解决方法

    第一步,谷歌有文章说CHtmlView部分api使用BSTR没释放: 解决方法是重写一下接口: CString GetFullName() const; CString GetFullName() c ...

  3. message() 信息提示

    //样式部分 .message { position: fixed;top: -100px;width: 400px;left: 50%;margin-left: -200px;z-index: 10 ...

  4. 《linux设备驱动开发详解》笔记——7并发控制

    linux中并发无处不在,底层驱动需要考虑. 7.1 并发与竞争 7.1.1 概念 并发:Concurrency,多个执行单元同时.并行执行 竞争:Race Condistions,并发的执行单元对共 ...

  5. poj 3669 火星撞地球问题 bfs算法

    题意:火星撞地球,你要跑到一个永远安全的地方,求最短时间 思路:bfs+预处理 这题的数据量比较大,所以需要进行预处理 对每个位置设上时间(被撞的最早时间) 未被撞的设为-1 for (int j = ...

  6. NOIP 2017 小凯的疑惑

    # NOIP 2017 小凯的疑惑 思路 a,b 互质 求最大不能表示出来的数k 则k与 a,b 互质 这里有一个结论:(网上有证明)不过我是打表找的规律 若 x,y(设x<y) 互质 则 : ...

  7. Linux学习-延伸正则表达式

    grep 默认仅支持基础正则表达式,如果要使用延伸型正则 表达式,你可以使用 grep -E , 不过更建议直接使用 egrep !直接区分指令比较好记忆!其 实 egrep 与 grep -E 是类 ...

  8. python字符串、列表和字典的说明

    python字符串.列表和字典的说明 字符串.列表.字典 字符串的作用存储一段数据信息.例如 info = '我爱北京天安门' ,在调取的时候可以直接调取,灵活方便,print(info) 就可以把刚 ...

  9. django中的objects.get和objects.filter方法的区别

    为了说明它们两者的区别定义2个models class Student(models.Model): name = models.CharField('姓名', max_length=20, defa ...

  10. loj2276 「HAOI2017」新型城市化

    给出的图是一个二分图(显然--吗),一个图的最大团=其补图的最大独立集,因此二分图的最大独立集就是补图的最大团. 欲使补图最大团变大,则要最大独立集变大.二分图最大独立集=点数-最小点覆盖.最小点覆盖 ...