让我们异或吧

题目描述

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

在生活中…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。

这题其实很简单
比如说要查询u和v的xor
设tmp为u和v的lca(最近公共祖先)
dis[x]表示x到根的xor
xor有一个性质:x ^ y ^ y = x
就是说将一个数xor两遍另一个数还是那个数
因为dis[u]其中有一部分是dis[tmp],把dis[tmp]异或掉就得到u到tmp的xor
那就将dis[u] ^ dis[tmp]再异或 dis[v] ^ dis[tmp]就得到答案了

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 100000 + 10;
int n,m,r,p,dis[maxn],dep[maxn],father[maxn][18];
vector<pair<int,int> > edges[maxn];
inline void dfs(int now,int f,int Xor) {  //dfs预处理
    dis[now] = Xor;
    for (size_t i = 0;i < edges[now].size();i++)
        if (edges[now][i].first != f) {
            dep[edges[now][i].first] = dep[now]+1;
            father[edges[now][i].first][0] = now;
            dfs(edges[now][i].first,now,Xor^edges[now][i].second);
        }
}
inline void init() {  //倍增
    for (int j = 1;j < 18;j++)
        for (int i = 1;i <= n;i++) father[i][j] = father[father[i][j-1]][j-1];
}
inline int lca(int a,int b) {  //求lca
    if (dep[a] < dep[b]) swap(a,b);
    for (int i = 0;i < 18;i++)
        if ((1<<i)&dep[a]-dep[b]) a = father[a][i];  //让深的点往上走
    if (a == b) return a;  //走到同一点
    for (int i = 18;i >= 0;i--)
        if (father[a][i] != father[b][i]) {  //两个一起往上走
            a = father[a][i];
            b = father[b][i];
        }
    return father[a][0];
}
int main() {
    scanf("%d",&n);
    for (int i = 1,u,v,w;i < n;i++) {
        scanf("%d%d%d",&u,&v,&w);
        edges[u].push_back(make_pair(v,w));
        edges[v].push_back(make_pair(u,w));
    }
    dfs(1,1,1);
    init();
    scanf("%d",&m);
    for (int i = 1,u,v;i <= m;i++) {
        scanf("%d%d",&u,&v);
        int tmp = lca(u,v);
        printf("%d\n",(dis[u]^dis[tmp])^(dis[v]^dis[tmp]));
    }
    return 0;
}

  

xor还满足结合律和交换律
我们将(dis[u]^dis[tmp])^(dis[v]^dis[tmp])打开
得到dis[u]^dis[v]^dis[tmp]^dis[tmp]
那么异或了两次dis[tmp]相当于没有异或
直接算dis[u]^dis[v]就可以了
所以我们就可以去掉求lca的部分
那么就只需要预处理出dis就可以了,一个dfs就行了

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 100000 + 10;
vector<pair<int,int> > edges[maxn];
int n,m,dis[maxn];
inline void dfs(int now,int f,int Xor) {
    dis[now] = Xor;
    for (size_t i = 0;i < edges[now].size();i++)
        if (edges[now][i].first != f) dfs(edges[now][i].first,now,Xor^edges[now][i].second);
}
int main() {
    scanf("%d",&n);
    for (int i = 1,u,v,w;i < n;i++) {
        scanf("%d%d%d",&u,&v,&w);
        edges[u].push_back(make_pair(v,w));
        edges[v].push_back(make_pair(u,w));
    }
    dfs(1,1,1);
    scanf("%d",&m);
    for (int i = 1,u,v;i <= m;i++) {
        scanf("%d%d",&u,&v);
        printf("%d\n",dis[u]^dis[v]);
    }
    return 0;
}

  

luogu2420 让我们异或吧的更多相关文章

  1. Luogu2420 让我们异或吧 (熟练剖分)

    \(dis[u] \bigoplus dis[v] = dis[u] \bigoplus dis[v] \bigoplus dis[lca\{x,y\}] \bigoplus dis[lca\{x,y ...

  2. Android数据加密之异或加密算法

    前言: 这几天被公司临时拉到去做Android IM即时通信协议实现,大致看了下他们定的协议,由于之前没有参与,据说因服务器性能限制,只达成非明文传递,具体原因我不太清楚,不过这里用的加密方式是采用异 ...

  3. Oracle数据库异机升级

    环境: A机:RHEL5.5 + Oracle 10.2.0.4 B机:RHEL5.5 需求: A机10.2.0.4数据库,在B机升级到11.2.0.4,应用最新PSU补丁程序. 目录: 一. 确认是 ...

  4. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  5. [PHP][位转换积累]之异或运算的简单加密应用

    异或的符号是^.按位异或运算, 对等长二进制模式按位或二进制数的每一位执行逻辑按位异或操作. 操作的结果是如果某位不同则该位为1, 否则该位为0. xor运算的逆运算是它本身,也就是说两次异或同一个数 ...

  6. Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5646   Accepted: 1226 Description In an ...

  7. RMAN异机恢复遭遇ORA-01547、ORA-01152、ORA-01110错误案例

    测试环境:     操作系统  :  Red Hat Enterprise Linux ES release 4 (Nahant Update 4)   VMWARE     数据库     :  O ...

  8. RAC异机恢复

    RAC异机恢复PDCL到PFCL: PNCL:RAC+ASM ,product env   db name:PNCL   instance:PDCL1 PDCL2 PFCL:RAC+ASM ,perf ...

  9. BZOJ 3261: 最大异或和

    Description 一个序列,支持两个操作. 1.在序列尾加入一个数. 2.询问 [l,r] 中与 x 异或值最大的数. \(n\leqslant 3*10^5\) Sol 可持久化 Trie 树 ...

随机推荐

  1. PHP机器学习库php-ml的简单测试和使用

    php-ml是一个使用PHP编写的机器学习库.虽然我们知道,python或者是C++提供了更多机器学习的库,但实际上,他们大多都略显复杂,配置起来让很多新手感到绝望.php-ml这个机器学习库虽然没有 ...

  2. 选择、冒泡排序,二分查找法以及一些for循环的灵活运用

    import java.util.Arrays;//冒泡排序 public class Test { public static void main(String[] args) { int[] ar ...

  3. Django学习(三)---Models(ORM框架)

    1) Django 中Models是与数据库相关的,与数据库相关的代码一般写在 models.py中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在sett ...

  4. MySQL数据库“十宗罪”(十大经典错误案例)

    Top  1: Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行) 问题还原 1 2 3 4 5 6 mysql> show variables lik ...

  5. python函数(2):函数进阶

    昨天说了函数的一些最基本的定义,今天我们继续研究函数.今天主要研究的是函数的命名空间.作用域.函数名的本质.闭包等等 预习: 1.写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的 ...

  6. 【SpringMVC】【EasyUI】关于使用EasyUIForm上传文件,返回JsonIE提示下载文件的解决办法!

    先说一下环境 EasyUI+SpringMVC+MyBatis 因为按正常手段,无法使用Ajax来提交一个包含文件的表单,故想到利用EasyUI的Form来提交,EasyUI的form封装了一套伪Aj ...

  7. (转)linux常用查看硬件设备信息命令

    场景:在一篇博客中看到这些总结性命令,感觉很实用就转载,以后用到进行相关的整理 系统 # uname -a # 查看内核/操作系统/CPU信息 # lsb_release -a # 查看操作系统版本 ...

  8. aspcms多图调用以及错误提示:3704

    1.“为师资介绍”(相册列表)建立了内容页(相册内容页), 需要对模板页面改造,在相册详细页调用多图,之前没有试过,这次利用: 实现多图调用,注意不能使用contentid=[content:id]  ...

  9. Java栈与堆 (转)

    1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于C ...

  10. php apache phpmyadmin mysql环境安装

    文件下载: Apache: http://httpd.apache.org/download.cgi PHP,phpMyAdmin,mysql,API下载:http://pan.baidu.com/s ...