思路(来自题解): 众所周知树上两个点xy的距离是deep[x]+deep[y]-deep[lca(x,y)]*2 然后我们把这个加减法换成异或,我们就会发现,deep[lca(x,y)]被消掉了 所以题目就简化成w是每个点的前缀异或和,只要找到一对最大的(x,y)让w[x]^w[y]最大就行了,这个经典问题用字典树就能解决了. 代码: #include<set> #include<map> #include<stack> #include<cmath> #…
题目描述 给定一棵 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,答案是…
给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n,表示树的节点数目. 接下来n-1行,每行包括三个整数u,v,w,表示节点u和节点v之间有一条边权重为w. 输出格式 输出一个整数,表示异或长度最大的路径的最大异或和. 数据范围 1≤n≤1000001≤n≤100000,0≤u,v<n0≤u,v<n,0≤w<2310≤w<231 输入样…
给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n,表示树的节点数目. 接下来n-1行,每行包括三个整数u,v,w,表示节点u和节点v之间有一条边权重为w. 输出格式 输出一个整数,表示异或长度最大的路径的最大异或和. 数据范围 1≤n≤1000001≤n≤100000,0≤u,v<n0≤u,v<n,0≤w<2310≤w<231 输入样…
对于字典树和01字典树的一点理解: 首先,字典树建树的过程就是按照每个数的前缀来的,如果你要存储一个全小写字母字符串,那么这个树每一个节点最多26个节点,这样的话,如果要找特定的单词的话,按照建树的方式找就可以了. 然后是01字典树,这个树在处理一些异或问题的时候特别好用,首先在存储一个树的过程中,我们是按照从高位开始的,如果是对于int型的,我们就从这个数的32位开始存储,不够的话,按照0补,这是建树的过程.再就是查询的时候,对于给定的数,我们先去找这一位上和他不同的,比如说,如果当前这个数的…
Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u与x的gcd可以被k整除,u不大于s-x,且与x的异或和最大. 思路:之前没有碰到过异或和最值的问题,所以是懵逼的.学习了01字典树后把这题补出来. 碰到操作①就上树,上树过程中注意不断维护每个节点往后路径中的最小值(具体见代码细节): 碰到操作②,如果k==1,那么从树上找数的同时注意限制条件最小…
<题目链接> 题目大意: 给定一颗$n$个节点$(n\leq10^5)$,有边权的树,其边权$(0\leq w < 2^{31})$.让你求出这棵树上任意两个节点之间的异或最大值. 解题分析: 先用DFS预处理出根节点到所有节点的路径异或值,然后任意两点$u,v$之间的路径异或值就能通过 $(u->rt) xor (v->rt)$的异或值得到,因为根节点到u.v的最近公共祖先的路径被异或了两次,所以能够直接得到u,v之间的异或距离.但是因为节点数量有$10^5$个,直接枚举两…
<题目链接> 题目大意: 给定n个数,进行m次查找,每次查找输出n个数中与给定数异或结果最大的数. 解题分析: 01字典树模板题,01字典树在求解异或问题上十分高效.利用给定数据的二进制数进行建树,然后在查找的时候,利用贪心的策略,优先寻找与当前位数的0.1值不同的路线,从而达到异或值最大的目的. #include <bits/stdc++.h> using namespace std; typedef long long ll; ; int n,m,pos; ll val[N*]…
<题目链接> 题目大意: 给定两个长度为n的序列,可以改变第二个序列中数的顺序,使得两个序列相同位置的数异或之后得到的新序列的字典序最小. 解题分析: 用01字典树来解决异或最值问题.因为是改变第二个序列的顺序,即按照第一个序列的顺序输出异或结果,所以我们将第二个序列建树.然后用第一个序列在树上进行查询.然后就是01字典树基本操作,因为每个数能够被使用一次,所以每个节点加上$num[N]$数组标记,并且加上del操作. #include <bits/stdc++.h> using…
Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 801    Accepted Submission(s): 302 Problem Description Monkey A lives on a tree, he always plays on this tree. One day, monkey…
Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 2920    Accepted Submission(s): 1264 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze…
题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中,与\(x\)进行异或运算(Xor), 得到的最大值为多少. 分析 前置知识:通过01字典树可以贪心的得到一个数与若干个数中进行异或运算的最大值. 在这里每次询问我们要得到\(a[L]\)至\(a[R]\)的数与\(x\)进行异或运算的最大值,每次建立区间\([L,R]\)的字典树来查询的话会超时而且浪费了…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 题解:一到01字典树的模版题,01字典树就是就是将一些树用二进制放到一个树上这样可以方便对整体异或处理. #include <iostream> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; ; * M][]; int node_size; ll val[…
题意:给定两个长为n的数组a和b:重新排列a和b,生成数组c,c[i]=a[i] xor b[i]:输出字典序最小的c数组. 分析:将a中的数插入一颗01字典树a中:将b中的数插入一颗01字典树b中:在trie树上查找n次,每次同时在a和b中下移一层:if 能同时走0,则同时走0:else if 能同时走1,则同时走1:else if 树a能走0&&树b能走1,则a走0.b走1:else if 树a能走1&&树b能走0,则a走1.b走0:else 向c中插入一个新数为这两个…
A. 全部空的放狗 B. 先O(NLOGNLOGN)处理出一个合数质因数中最大的质数是多少 因为p1 x1 x2的关系是 x2是p在x1之上的最小倍数 所以x1的范围是[x2-p+1,x2-1]要使最后答案尽可能小 要包含尽可能多的选择 p0 x0  x1关系同上 #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\…
牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \(sum_{(u, v)}=sum_{(u, 1)} \bigoplus sum_{(v, 1)}\)那么我们可以预处理出所有简单路径上的异或值 对于路径上的最大权值来说,建图后,我们可以将边权进行排序,对于每一个权值为\(w_i(1-n)\)的连通块 现在我们已经得到了当前边权所在的连通块了,所以…
字典树 概述     字典树,又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高.(引自百度百科<字典树>) 光说不懂,上引例-- NKOJ 1934 外地人     你考入大城市沙坪坝的学校, 但是沙坪坝的当地人说着一种很难懂的方言, 你完全 听不懂. 幸好你手中有本字典可以帮你…
HDU5589 Tree 题意: 给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\) 题解: 对于两点\(u,v\)之间的路径上的边权的异或和,可以转化为根到点\(u\)的路径上异或和与根到点\(v\)的路径上异或和的异或和,所以可以与处理出根到各个点的路径边权异或和 接下来就变成了一个序列上的问题了,每次询问区间\([L,R]\)之间的点有多少对的异或和大于\(M\) 然后就可以用莫队来处理,为了能快速…
Query on A Tree Problem Description Monkey A lives on a tree, he always plays on this tree. One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once. Monkey A gave a v…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:有一个数组a[], 包含n个数,从n个数中找到三个数使得 (a[i]+a[j])⊕a[k]最大,i,j,k不同; 求异或的结果最大所以我们可以用01字典树,先把所有的数加入字典树中,从n个数中选出两个数a[i]和a[j], 先把他们从字典树中删除,然后找到与a[i]+a[j]异或最大的数,和结果取最大值即可: 最后不要忘记再把a[i]和a[j]添加到字典树中即可: #include<st…
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4825 题意:有n个数m个查找,每个查找有一个数x, 从序列中找到一个数y,使得x异或y最大,输出y: 把已知序列建立01字典树,然后查找即可:就是把十进制数x装换成二进制01,因为数在int范围内,所以可以前补零构成32位,按顺序插入即可: #include<iostream> #include<algorithm> #include<string.h> #in…
A.Beru-taxi 水题:有一个人站在(sx,sy)的位置,有n辆出租车,正向这个人匀速赶来,每个出租车的位置是(xi, yi) 速度是 Vi;求人最少需要等的时间: 单间循环即可: #include<iostream> #include<algorithm> #include<string.h> #include<stdio.h> #include<math.h> #include<vector> using namespace…
根据二进制建一棵01字典树,每个节点的答案等于左节点0的个数 * 右节点1的个数 * 2,遍历整棵树就能得到答案. AC代码: #include<cstdio> using namespace std; const int mod=998244353; const int maxn=2; struct node{ node *next[maxn]; //0 1节点 int cnt,level; node(){ cnt=0; level=0; next[0]=NULL; next[1]=NULL…
As you might remember from the previous round, Vova is currently playing a strategic game known as Rage of Empires. Vova managed to build a large army, but forgot about the main person in the army - the commander. So he tries to hire a commander, and…
题意:中文题意 解题思路:01字典树板子题 代码: #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define maxn 100050 #define ll long long using namespace std; int trie[maxn*32][2]; ll val[maxn*32]; ll x,y; int root; int tot; int…
D. Vitya and Strange Lesson 题意 数列里有n个数,m次操作,每次给x,让n个数都异或上x.并输出数列的mex值. 题解 01字典树保存每个节点下面有几个数,然后当前总异或的是sw,则sw为1的位的节点左右孩子交换(不用真的交换).左孩子的值小于左边总节点数则mex在左子树,否则在右子树. 代码 const int N=531000;//3e5<2^19<N int sw=0; struct Trie{ int ch[N*20][2]; int cnt[N*20];…
题意: 给一个集合,多次询问,每次给一个k,问你集合和k异或结果最大的哪个 题解: 经典的01字典树问题,学习一哈. 把一个数字看成32位的01串,然后查找异或的时候不断的沿着^为1的路向下走即可 #include <bits/stdc++.h> #define endl '\n' #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(ii,a,b) for(int ii=a;ii<=b;++i…
一般异或问题都可以转换成字典树的问题,,我一开始的想法有点小问题,改一下就好了 下面的代码是逆向建树的,数据量大就不行 /*3 01字典树 根据异或性质,a1!=a2 ==> a1^x1^..^xn != a2^x1^..an 把修改转换成不同的询问 先把初始集合里没有的数建立成字典树 每次询问找的是字典树里异或x最小的值 */ #include<bits/stdc++.h> using namespace std; #define maxn 300005 int buf[maxn];…
<题目链接> 题目大意:给定一个序列,现在求出两段不相交的区间异或和的最大值. 解题分析: 区间异或问题首先想到01字典树.利用前缀.后缀建树,并且利用异或的性质,相同的两个数异或变成0,从而将前缀操作转化为区间操作,比如:$(a_1 \oplus a_2)\oplus(a_1 \oplus a_2 \oplus a_3 \oplus a_4) = a_3 \oplus a_4$.然后利用简单的$dp$,$predp[i]$记录前$[1~i]$ 任意区间的区间异或最大值(注意不是前缀),$nx…
<题目链接> 题目大意: 给定一个数字序列,让你从中找出三个不同的数,从而求出:$\max_{i,j,k} (s_i+s_j) \oplus s_k$的值. 解题分析:先建好01字典树,然后枚举两个不同的数,从字典树中删除这两个数,然后进行匹配,找到能够使 $ (s_i+s_j) \oplus s_k$ 值最大的值.之后再将这两个数插入,进行下一轮询问. #include <bits/stdc++.h> using namespace std; #define clr(a,b) m…