P2420 让我们异或吧(树链剖分)
题目描述
异或是一种神奇的运算,大部分人把它总结成不进位加法.
在生活中…xor运算也很常见。比如,对于一个问题的回答,是为1,否为0.那么:
(A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣
好了,现在我们来制造和处理一些复杂的情况。比如我们将给出一颗树,它很高兴自己有N个结点。树的每条边上有一个权值。我们要进行M次询问,对于每次询问,我们想知道某两点之间的路径上所有边权的异或值。
输入输出格式
输入格式:
输入文件第一行包含一个整数N,表示这颗开心的树拥有的结点数,以下有N-1行,描述这些边,每行有3个数,u,v,w,表示u和v之间有一条权值为w的边。接下来一行有一个整数M,表示询问数。之后的M行,每行两个数u,v,表示询问这两个点之间的路径上的权值异或值。
输出格式:
输出M行,每行一个整数,表示异或值
输入输出样例
输入样例#1: 复制
5
1 4 9644
2 5 15004
3 1 14635
5 3 9684
3
2 4
5 4
1 1
输出样例#1: 复制
975
14675
0
说明
对于40%的数据,有1 ≤ N,M ≤ 3000;
对于100%的数据,有1 ≤ N ,M≤ 100000。
题解
怎么说呢。
就是一个简单的树剖边转点。
在第一遍dfs的时候,我们把边权放到儿子节点上去,因为父亲节点有可能有多个儿子,但我们的边权是唯一的,而儿子到父亲的边也是唯一的,所以我们就可以把边权放到儿子节点上去。
在求LCA的时候我们就只要正常统计,而不计算LCA的值就OK了因为LCA的值不会属于这条路径,仔细想想??
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m;
int size[N],son[N],top[N];
int tot,l[N],dep[N],fa[N],ch[N],a[N];
int sum[N<<4];
int num,head[N];
struct node{
int to,v,next;
}e[N<<1];
void add(int from,int to,int v){
num++;
e[num].to=to;
e[num].v=v;
e[num].next=head[from];
head[from]=num;
}
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
void dfs1(int x){
size[x]=1;
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(!dep[v]){
ch[v]=e[i].v;
dep[v]=dep[x]+1;fa[v]=x;
dfs1(v);size[x]+=size[v];
if(size[son[x]]<size[v])son[x]=v;
}
}
}
void dfs2(int x,int tp){
l[x]=++tot;a[tot]=ch[x];top[x]=tp;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v!=fa[x]&&v!=son[x])dfs2(v,v);
}
}
void build(int root,int left,int right){
if(left==right){
sum[root]=a[left];
return ;
}
int mid=(left+right)>>1;
build(root<<1,left,mid);
build(root<<1|1,mid+1,right);
sum[root]=sum[root<<1]^sum[root<<1|1];
}
int query(int root,int left,int right,int l,int r){
if(left>r||right<l)return 0;
if(left>=l&&right<=r)return sum[root];
int mid=(left+right)>>1;
int a=0,b=0;
if(mid>=l) a=query(root<<1,left,mid,l,r);
if(mid<r) b=query(root<<1|1,mid+1,right,l,r);
return a^b;
}
int cal(int x,int y){
int ans=0,fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y);
ans^=query(1,1,n,l[fx],l[x]);
x=fa[fx],fx=top[x];
}
if(dep[x]>dep[y])swap(x,y);
ans^=query(1,1,n,l[x],l[y])^ch[x];
return ans;
}
int main()
{
n=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z);
}
fa[1]=1;dep[1]=1;
dfs1(1);dfs2(1,1);
build(1,1,n);
m=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
printf("%d\n",x==y?0:cal(x,y));
}
return 0;
}
P2420 让我们异或吧(树链剖分)的更多相关文章
- P2420 让我们异或吧 (树链剖分,异或前缀和)
题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能 ...
- BZOJ 4568 [Scoi2016]幸运数字(树链剖分 + 异或线性基)
题目链接 BZOJ 4568 考虑树链剖分+线段树维护每一段区域的异或线性基 对于每个询问,求出该点集的异或线性基.然后求一下这个线性基里面能异或出的最大值即可. #include <bits ...
- 树链剖分好(du)题(liu)选做
1.luogu P4315 月下"毛景树" 题目链接 前言: 这大概是本蒟蒻A掉的题里面码量最大的一道题了.我自认为码风比较紧凑,但还是写了175行. 从下午2点多调到晚上8点.中 ...
- 【BZOJ-4568】幸运数字 树链剖分 + 线性基合并
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 238 Solved: 113[Submit][Status ...
- HDU 4897 Little Devil I(树链剖分)(2014 Multi-University Training Contest 4)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4897 Problem Description There is an old country and ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- HDU 5274 Dylans loves tree(树链剖分)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5274 [题目大意] 给出一棵树,每个点有一个权值,权值可修改,且大于等于0,询问链上出现次数为奇数 ...
- 从lca到树链剖分 bestcoder round#45 1003
bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或) ...
随机推荐
- sqluldr2linux64.bin的使用
使用sqluldr2linux64.bin的前提是已经安装了Oracle数据库,sqluldr2linux64.bin和Oracle在同一台主机上使用,使用之前需要赋予可执行权限: [root@nod ...
- Sublime使用随记
1.安装 Package Control Ctrl+` 打开命令行,执行如下代码: 适用于 Sublime Text 3: import urllib.request,os;pf='Package C ...
- HDU 1175 连连看【BFS】
题意:给出起点和终点的棋子,不能经过别的棋子,而且转弯的次数不能超过2次,问能否消除 和逃离迷宫一样,每个节点记录下来它的当前的方向和转弯的次数,再搜 注意特判起点的棋子和终点的棋子为0或者不一样的情 ...
- 有趣的console
博文第一篇,就以前端调试的“座上客”---console开始
- 用centos镜像 制作本地yum源
1.上传iso镜像 2.挂载镜像到相应目录 mkdir /yumiso #创建目录mount -t iso9660 /dev/cdrom/sr0 /yumiso #挂载镜像文件到对应目录 3.备份旧的 ...
- 紫书 习题8-14 UVa 1616(二分+小数化分数+精度)
参考了https://www.cnblogs.com/dwtfukgv/p/5645446.html (1)直接二分答案.说实话我没有想到, 一开始以为是贪心, 以某种策略能得到最优解. 但是想了很久 ...
- Object-C,对象和方法
学习Object-C,买了2本书,其中1本是用C币买的,总体质量一般,比较基础. 另外一本是,疯狂-李阳写的,大部头,比较吓人,比较全一点. 对于面向对象,之前还是有个大概的理解,再多点基础的例子. ...
- MarkDown 图片大小问题
本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50099843 MarkDown里显示图 ...
- Effective C++ 11-17
11.为须要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符. 显然,由于动态内存分配,绝对会有深浅拷贝的问题,要重写拷贝构造函数.使其为深拷贝,才干实现真正意义上的拷贝.这是我理解的关于要声明拷 ...
- 物理读之LRU(近期最少被使用)的深入解析
转载请注明出处: http://blog.csdn.net/guoyjoe/article/details/38264883 一组LRU链表包含LRU主链.LRU辅助链.LRUW主链,LRUW辅助链, ...