集合哈希(异或哈希,和哈希)
可以快速判断每个元素的出现次数是否等于预设值(加法和异或看着用吧),或者奇偶性。给每一个数字随一个 \([0,2^{64})\) 的权值,然后取集合内所有元素的权值之和即可。
P8819 [CSP-S 2022] 星战
有时,单次操作对可重集的改变较大,不好维护桶数组,但是加入哪些元素是确定的,可以快速维护每次操作对哈希值的改变,此时可以使用和哈希维护。
P10785 [NOI2024] 集合
qoj5017 相等树链
给定两棵树,问有多少个点集在两棵树上都是链。
\(n\le 2\times 10^5\)
对第二棵树点分治,问题转化为判断一条经过分治中心 \(rt\) 的路径 \(u\to rt\to v\) 在第一棵树上是否仍然是链。分讨这个链的两个端点是否在 T2 的同一棵子树内。若相同,那么链的全部信息就都被确定了,容易维护链上所有点组成集合的哈希,也容易得出缺少的节点组成集合的哈希。链的两端点就是点集的直径。
若不同,设 T2 上 \(u\to rt\) 之间的点组成集合 \(X\),\(rt\to v\) 之间的点(不含 \(rt\))组成集合 \(Y\),将 T1 上的链按 \(rt\) 划分为 \(L,R\) 两半,不妨设 \(L\) 部分的端点属于集合 \(X\)。
那么有关系式:\(X+Y=L+R\),也即 \(X-L=Y-R\),这样 T1 上路径两端点就相互独立了。判定过程中取 \(X,Y\) 为 T2 中分治中心到某一点的路径,\(L\) 为 T1 上 \(X\) 组成连通块的直径两端点 \(a,b\) 到 \(rt\) 的路径(两条路径都算一遍就可以,不用分讨了),\(R\) 同理,也用哈希表维护。时间复杂度 \(O(n\log n)\)。这里哈希不能用异或。