P2420 让我们异或吧

题目描述

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

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

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

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

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

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring> #define N 1010100
using namespace std; int n,m,head[N],tot;
struct nodE {
int to,next,w;
} e[N]; void add(int u,int v,int w) {
e[++tot].to=v,e[tot].next=head[u],head[u]=tot,e[tot].w=w;
} int p[N][],f[N][],dep[N];
void dfs(int u,int fa,int w) {
dep[u]=dep[fa]+,f[u][]=fa,p[u][]=w;
for(int i=; (<<i)<=dep[u]; i++)
f[u][i]=f[f[u][i-]][i-],p[u][i]=p[u][i-]^p[f[u][i-]][i-];
for(int i=head[u]; i; i=e[i].next) {
int v=e[i].to;
if(v==fa) continue;
dfs(v,u,e[i].w);
}
} int lca(int u,int v) {
int an=;
if(dep[u]>=dep[v]) swap(u,v);
for(int i=; i>=; i--) {
if(dep[u]<=dep[v]-(<<i)) {
if(!an) an=p[v][i];
else an^=p[v][i];
v=f[v][i];
}
}
if(u==v) return an;
for(int i=; i>=; i--) {
if(f[u][i]!=f[v][i]) {
if(!an) an=p[v][i]^p[u][i];
else an^=p[v][i],an^=p[u][i];
u=f[u][i],v=f[v][i];
}
}
if(v==) return an^p[u][];
else if(u==) return an^p[v][];
return an^p[u][]^p[v][];
} int main() {
scanf("%d",&n);
for(int u,v,w,i=; i<n; i++) {
scanf("%d%d%d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
dfs(,,);
scanf("%d",&m);
for(int u,v,i=; i<=m; i++) {
scanf("%d%d",&u,&v);
printf("%d\n",lca(u,v));
} return ;
}

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

抑或: $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]$

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

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring> #define N 1010100
using namespace std; int n,m,head[N],tot;
struct nodE {
int to,next,w;
} e[N]; void add(int u,int v,int w) {
e[++tot].to=v,e[tot].next=head[u],head[u]=tot,e[tot].w=w;
} int dis[N];
void dfs(int u,int fa,int Xor){
dis[u]=Xor;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v!=fa) dfs(v,u,Xor^e[i].w);
}
}
int main() {
scanf("%d",&n);
for(int u,v,w,i=; i<n; i++) {
scanf("%d%d%d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
dfs(,,);
scanf("%d",&m);
for(int u,v,i=; i<=m; i++) {
scanf("%d%d",&u,&v);
printf("%d\n",dis[u]^dis[v]);
} return ;
}

洛谷——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. pagefile.sys

    pagefile.sys

  2. YTU 2503: 大斐波那契数列

    2503: 大斐波那契数列 时间限制: 1 Sec  内存限制: 200 MB 提交: 974  解决: 400 题目描述 斐波那契数列,又称黄金比例数列,指的是这样一个数列:0.1.1.2.3.5. ...

  3. iOS方法重写

    在O-C中子类可以继承父类的方法 ,而不需要从新编写相同的方法,但是有有时候子类并不想原封不动的继承父类的方法,而且是想做一些修改,这就采用啦方法的重写,方法从写有叫做方法覆盖,若子类的中的方法与父类 ...

  4. BZOJ_1692_[Usaco2007 Dec]队列变换_后缀数组

    BZOJ_1692_[Usaco2007 Dec]队列变换_后缀数组 Description FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛” ...

  5. POJ 2104 HDU 2665 主席树 解决区间第K大

    两道题都是区间第K大询问,数据规模基本相同. 解决这种问题, 可以采用平方划分(块状表)复杂度也可以接受,但是实际表现比主席树差得多. 这里大致讲一下我对主席树的理解. 首先,如果对于某个区间[L,R ...

  6. sql的where条件中包含中文,查询不出来的处理方法

    SELECT  * FROM phonenumber_info where PROVANCE=N'广东' and  CITY=N'中山市'

  7. source命令用法(转载)

    转自:http://zhidao.baidu.com/link?url=mNfsPHSjTEm7llgyMYx0UVNwkJmD_cxLeHtZnHcM6Ms8LDXofVHka_EzHi6GltbR ...

  8. Java方式 MySQL数据库连接

    JDBC-ODBC : 桥连就是将对JDBC API的调用转换为对另一组数据库连接(即 ODBC) API 的调用 JDBC-ODBC桥连方式驱动类是: sun.jdbc.odbc.JdbcOdbcD ...

  9. 用Movie显示gif(2)GifView

    1,类 import android.annotation.SuppressLint; import android.content.Context; import android.content.r ...

  10. 【转】mysql INSERT的用法

    转自:http://www.cnblogs.com/ggjucheng/archive/2012/11/05/2754938.html insert的语法 INSERT [LOW_PRIORITY | ...