P2420 让我们异或吧

题目描述

异或是一种神奇的运算,大部分人把它总结成不进位加法.

在生活中…xor运算也很常见。比如,对于一个问题的回答,是为1,否为0.那么:

(A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣

好了,现在我们来制造和处理一些复杂的情况。比如我们将给出一颗树,它很高兴自己有N个结点。树的每条边上有一个权值。我们要进行M次询问,对于每次询问,我们想知道某两点之间的路径上所有边权的异或值。

维护父节点的同时维护抑或值

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5.  
  6. #define N 1010100
  7. using namespace std;
  8.  
  9. int n,m,head[N],tot;
  10. struct nodE {
  11. int to,next,w;
  12. } e[N];
  13.  
  14. void add(int u,int v,int w) {
  15. e[++tot].to=v,e[tot].next=head[u],head[u]=tot,e[tot].w=w;
  16. }
  17.  
  18. int p[N][],f[N][],dep[N];
  19. void dfs(int u,int fa,int w) {
  20. dep[u]=dep[fa]+,f[u][]=fa,p[u][]=w;
  21. for(int i=; (<<i)<=dep[u]; i++)
  22. f[u][i]=f[f[u][i-]][i-],p[u][i]=p[u][i-]^p[f[u][i-]][i-];
  23. for(int i=head[u]; i; i=e[i].next) {
  24. int v=e[i].to;
  25. if(v==fa) continue;
  26. dfs(v,u,e[i].w);
  27. }
  28. }
  29.  
  30. int lca(int u,int v) {
  31. int an=;
  32. if(dep[u]>=dep[v]) swap(u,v);
  33. for(int i=; i>=; i--) {
  34. if(dep[u]<=dep[v]-(<<i)) {
  35. if(!an) an=p[v][i];
  36. else an^=p[v][i];
  37. v=f[v][i];
  38. }
  39. }
  40. if(u==v) return an;
  41. for(int i=; i>=; i--) {
  42. if(f[u][i]!=f[v][i]) {
  43. if(!an) an=p[v][i]^p[u][i];
  44. else an^=p[v][i],an^=p[u][i];
  45. u=f[u][i],v=f[v][i];
  46. }
  47. }
  48. if(v==) return an^p[u][];
  49. else if(u==) return an^p[v][];
  50. return an^p[u][]^p[v][];
  51. }
  52.  
  53. int main() {
  54. scanf("%d",&n);
  55. for(int u,v,w,i=; i<n; i++) {
  56. scanf("%d%d%d",&u,&v,&w);
  57. add(u,v,w),add(v,u,w);
  58. }
  59. dfs(,,);
  60. scanf("%d",&m);
  61. for(int u,v,i=; i<=m; i++) {
  62. scanf("%d%d",&u,&v);
  63. printf("%d\n",lca(u,v));
  64. }
  65.  
  66. return ;
  67. }

普及一下有关抑或的知识:

抑或: $0^0=0,1^1=0,1^0=1,0^1=1$

观察发现只有二进制位相同时,那一位的抑或值才为真

抑或的几个常用性质:

1.交换律:$a\^b=b\^a$ 显然

2.结合律:$a\^b\^c=a\^(b\^c)$ 显然

3.抑或自己 $a\^a=0$ 显然

4.抑或0 $a\^0=a$ 显然

设$dis[u]$为节点1到$u$所经过路径上的抑或值

那么本题要求就是$(dis[u]^dis[lca(u,v)])^(dis[v]^dis[lca(u,v)])$

因为抑或自己为0,而抑或0为自己,那么1到点u再抑或1到点$lca(u,v)$,就相当于点u抑或了$lca(u,v)$

毫无疑问,抑或满足结合律$(dis[u]^dis[v])^(dis[lca(u,v)]^dis[lca(u,v)])$

由性质3,4得出$ans=dis[u]^dis[v]$

极其简短的代码以及神奇的性质:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5.  
  6. #define N 1010100
  7. using namespace std;
  8.  
  9. int n,m,head[N],tot;
  10. struct nodE {
  11. int to,next,w;
  12. } e[N];
  13.  
  14. void add(int u,int v,int w) {
  15. e[++tot].to=v,e[tot].next=head[u],head[u]=tot,e[tot].w=w;
  16. }
  17.  
  18. int dis[N];
  19. void dfs(int u,int fa,int Xor){
  20. dis[u]=Xor;
  21. for(int i=head[u];i;i=e[i].next){
  22. int v=e[i].to;
  23. if(v!=fa) dfs(v,u,Xor^e[i].w);
  24. }
  25. }
  26. int main() {
  27. scanf("%d",&n);
  28. for(int u,v,w,i=; i<n; i++) {
  29. scanf("%d%d%d",&u,&v,&w);
  30. add(u,v,w),add(v,u,w);
  31. }
  32. dfs(,,);
  33. scanf("%d",&m);
  34. for(int u,v,i=; i<=m; i++) {
  35. scanf("%d%d",&u,&v);
  36. printf("%d\n",dis[u]^dis[v]);
  37. }
  38.  
  39. return ;
  40. }

洛谷——P2420 让我们异或吧的更多相关文章

  1. 洛谷 P2420 让我们异或吧 解题报告

    P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...

  2. 洛谷 [P2420] 让我们异或吧

    某两点之间的路径上所有边权的异或值即dis1^dis2--^disn. 由于x^y^y=x,所以dfs预处理出每一点到根节点的异或值,对于每次询问,直接输出 disu^disv. #include & ...

  3. 洛谷P2420 让我们异或吧(树链剖分)

    题目描述异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能够 ...

  4. [洛谷P2420] 让我们异或吧

    题目链接:让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是 ...

  5. ⌈洛谷4735⌋⌈BZOJ3261⌋最大异或和【可持久化01Trie】

    题目链接 [BZOJ传送门] [洛谷传送门] 题解 终于学会了可持久化trie树了.感觉并不是特别的难. 因为可持久化,那么我们就考虑动态开点的trie树. 都知道异或操作是有传递性的,那么我们就维护 ...

  6. 【洛谷P2420】让我们异或吧

    题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能 ...

  7. AC日记——让我们异或吧 洛谷 P2420

    题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能 ...

  8. skkyk:题解 洛谷P2420 【让我们异或吧】lca+xor前缀和

    刚学了LCA,写篇题解巩固一下 首先题目有误: (A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣,这句话显然是错误的qwq 对于这道题,容易看出,对于待处理的两个点,只要我们找到他的 ...

  9. 洛谷P4551 最长异或路径

    传送门:https://www.luogu.org/problem/show?pid=4551 在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大. 一种很不错的做 ...

随机推荐

  1. Python获取CPU、内存使用率以及网络使用状态代码

    Python获取CPU.内存使用率以及网络使用状态代码_python_脚本之家 http://www.jb51.net/article/134714.htm

  2. HDU 5754Life Winner Bo

    Life Winner Bo Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  3. MAC OS brew安装MNMP

    安装HomeBrew Brew是Mac下面的包管理工具,就像centos下面的yum一样.HomeBrew可以通过ruby来安装,mac系统是自带ruby的,所以只要在终端运行下面的代码即可安装Hom ...

  4. [NOIP 2010] 引入入城

    [题目链接] https://loj.ac/problem/2595 [算法] 显然 , 每个第一行的成市控制的一定是一段区间 那么 , 问题就转化为了经典的区间覆盖问题 , 贪心即可 , 时间复杂度 ...

  5. Java序列化系列教程(上)

    一定义以及相关概念 互联网的产生带来了机器间通讯的需求,而互联通讯的双方需要采用约定的协议,序列化和反序列化属于通讯协议的一部分.通讯协议往往采用分层模型,不同模型每层的功能定义以及颗粒度不同,例如: ...

  6. 基于Spark的GBDT + LR模型实现

    目录 基于Spark的GBDT + LR模型实现 数据预处理部分 GBDT模型部分(省略调参部分) GBDT与LR混合部分 基于Spark的GBDT + LR模型实现 测试数据来源http://arc ...

  7. SQL Server 方言类型映射问题

    关于SQL Server的类型映射问题,例如,nvarchar无法进行hibernate类型映射,需要通过convert进行类型转换方可进行获取

  8. bzoj 1631: [Usaco2007 Feb]Cow Party【spfa】

    正反加边分别跑spfa最短路,把两次最短路的和求个max就是答案 #include<iostream> #include<cstdio> #include<queue&g ...

  9. js 事件循环机制 EventLoop

    js 的非阻塞I/O  就是由事件循环机制实现的 众所周知  js是单线程的 也就是上一个任务完成后才能开始新的任务 那js碰到ajxa和定时器.promise这些异步任务怎么办那?这时候就出现了事件 ...

  10. zabbix详细介绍及其自动动态发现

    zabbix3.2.1 第1章 安装 1.1 查看系统环境 [root@centos7-2 ~]# [root@centos7-2 ~]# hostname -I 10.0.0.10 172.16.1 ...