题目链接 [BZOJ传送门] [洛谷传送门] 题解 终于学会了可持久化trie树了.感觉并不是特别的难. 因为可持久化,那么我们就考虑动态开点的trie树. 都知道异或操作是有传递性的,那么我们就维护一个前缀异或和. [最长异或距离] 可以参考以上这一道题目的贪心策略. 每次找到另外一边的(说的清楚一点就是每一次找字典树的儿子都找异或的数当前这一位的异或1的值),这样可以保证疑惑后答案最大. 参照主席树的区间最小的求法:[洛谷的模板] 每一次我们就查找root[l - 1] ~ root[r]区…
$ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 \(1\) 到 \(n\).第 \(i\) 种馅儿具有一个非负整数的属性值 \(a_i\).每种馅儿的数量都足够多,即小粽不会因为缺少原料而做不出想要的粽子.小粽准备用这些馅儿来做出 \(k\) 个粽子. 小粽的做法是:选两个整数数 \(l\), \(r\),满足 \(1 \leqslant l…
题目大意:给你一个长方形矩阵,位置$i,j$上的数是$a_{i}\;xor\;b_{j}$,求某个子矩阵内第$K$大的值 最先想的是二分答案然后验证,然而是$O(qnlogmloga_{i})$,不出意外会被卡..看完题解才恍然大悟 $01Trie$是具有二分性质的!因为每个节点最多有2个儿子! 先对$b$序列建可持久化$01Trie$,记录一个$sum$表示当前节点的子树内有多少个数 对于每次询问,因为$n$很小,暴力枚举$a$进行统计,记录每个a当前在01Trie的位置 接下来就是在$01T…
题目大意:给你一个序列,求出第$K$大的两两异或值 先建出来可持久化$01Trie$ 用一个$set$/堆存结构体,存某个异或对$<i,j>$的第二关键字$j$,以及$ai\;xor\;aj$的值,堆中按异或值从小到大排序 每次取出一对$<i,j>$并把它从堆中删除 在$[0,j-1]$的 可持久化$01Trie$ 中把$a_{i}$这个数删除 再查询$[0,j-1]$中和$a_{j}$的异或最大值,重新推入堆中... 反复操作$K$次即可 删除操作中的细节比较多 #include…
题目大意:让你维护一个序列,支持在序列末插入一个数,支持询问$[l,r]$区间内选择一个位置$p$,使$xor\sum_{i=p}^{n}a_{i}$最大 可持久化$01Trie$裸题,把 区间异或和 转化为区间端点前缀异或和的异或值 即求$xsum_{n}\;xor\;max(xsum_{i})i\in[l-1,r-1]$的最大值 那么在可持久化$01Trie$里是$r-1$的$Trie$对$l-2$的$Trie$做差 需要先把$0$推入$Trie$里 #include <cmath> #i…
某两点之间的路径上所有边权的异或值即dis1^dis2--^disn. 由于x^y^y=x,所以dfs预处理出每一点到根节点的异或值,对于每次询问,直接输出 disu^disv. #include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> using namespace std; int read(){ int rv=0,fh=1; char c=getchar(…
传送门:https://www.luogu.org/problem/show?pid=4551 在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大. 一种很不错的做法是将n个数按二进制从最高位到低位建立一个trie树,然后把m放在trie树上跑一遍. 因为是从高位到低位存的,所以对于每一位,我们只要贪心让这一位的异或值得1.即如果m得当前位是1,就在trie树上找0:否则就找1.若能找到,ans的这一位就是1,否则是0. 如果上述这道水题会了的话,这道题就不难…
P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣 好了,现在我们来制造和处理一些复杂的情况.比如我们将给出一颗树,它很高兴自己有N个结点.树的每条边上有一个权值.我们要进行M次询问,对于每次询问,我们想知道某两点之间的路径上所有边权的异或值. 输入输出格式 输入格式: 输入文件第一行包含一个整数N,表示这颗开心…
题目大意:给定一个长度为 N 的序列,支持两个操作:在序列末尾添加一个新的数字,查询序列区间 \([l,r]\) 内使得 \(a_p\oplus a_{q+1}\oplus ... a_N\oplus x\) 值最大. 题解:由于是查询区间的最大异或值,可知应该使用可持久化数据结构,再由于是最大异或和,可知采用可持久化 Trie + 前缀和处理.在 Trie 的每个节点上维护一个信息,表示该节点是哪个最新的数的某一位,注意无节点的位置这个值要被赋予 -1. 代码如下 #include <bits…
传送门 直接把每个点到根节点的异或距离插入01trie. 然后枚举每个点在01trie上匹配来更新答案就行了. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getch…