可持久化相关题目整理

来源:互联网 发布:华润电力 知乎 编辑:程序博客网 时间:2024/05/17 08:46
  1. hdu 5788 Level Up 对dfs序建立主席树,两个dfs序对应线段树之间的差值就是对应线段的差值,用主席树处理一棵子树的中位数,这种树问题里计算子节点的改变对父节点的影响的题目,很多时候会在dfs中用树状数组维护相关信息。
  2. hdu 5790 Prefix 询问一个区间有几个不同的树,对每个(l, r)询问,在r对应的线段树里求[l, r]的区间和就好,对前缀的判断自己一开始还想用hash值,其实直接在字典树里记录对应前缀之前出现的位置就好。
  3. CodeChef XRQRS 多个操作,可持久化字典树和线段树的组合体,正常写就好了,利用线段树之间的差值来确定区间的线段树。
  4. HihoCoder 1232 给两颗树,每次询问两个树上两条到根路径中相同编号的点中深度最大的那个。将一个树树链剖分,另一个树以树链剖分的重编号为下标,实际点的编号为最值建立线段树,可持久化,那么找到一条路径对应的线段树,另一条路径在里面查出最值就好了。事实证明数据范围不超过10的题都是最适合瞎搞的,n2的lca瞎搞各种复杂度比主席树低。
  5. bzoj 4628 三种操作,一个是插入一个01串,一个是删去一个01串,不管什么时候保证某个询问的01串在这些01串里的最大公共前缀只有一个,第三个操作是询问某个01串在一个时间区间l, r里对应的lcp的变化次数。不强制在线就不用可持久化,加一个lazy记录以这个串为答案的变化次数,如果一个节点做为一个原有的01串,那么lazy就不用传递下去,询问的时候直接把对应节点的val值取出来就好。
  6. bzoj 4571 n个数,问[l, r]区间里每个数加上x后与b异或的最大值,可持久化,然后针对每个数加上b,就是平移整个线段树,另外线段树可以看作是一棵满字典树,像在字典树上查询就好了
  7. HihoCoder 1046 长度为n的序列有n2个子序列,每个子序列的价值是序列内所有数字之和(重复数字只计算一次),问第k大的子序列价值,区间更新主席树,需要注意的是lazy不能下传,而是在pushup的时候用lazy更新上传上来的答案,然后利用优先队列经典地求第k大,每次拿出一个数,就把对应线段树的对应位置置为-inf
  8. bzoj 4026 水题,问一个区间不同颜色个数的题都是在r对应的线段树里查询[l, r]区间
  9. bzoj 2653 给n个数字,问左端点在[a, b],右端点在[c, d]的序列中每个序列的中位数的最大值。总共n个数,最多只有n个中位数,离散化这些中位数,利用可持久化分别建立线段树,对每个中位数对应的线段树,比它小的数所在位置标-1,其它标1,二分就可以找到一个区间对应的中位数,然后再记录一个区间左右端点能拓展出的最大值,就可以确定出最大的中位数。除了建树是可持久化,其它都是线段树操作。
  10. bzoj 3218 神题,可持久化线段树优化网络流
  11. hdoj 5709 线段树合并,给一颗树,树上每个节点有颜色,强制在线询问一个节点的子树中距该节点距离不超过d的节点有一个不同的颜色。把0做为一个虚点,每个节点建两棵线段树,T1[x]维护x子树内,深度在[l,r]内的点数,同种颜色有多个的话,保留深度最小的那个。T2[x]维护x子树内每种颜色的最小深度。从底向上合并线段树,先合并T1,然后合并T2的时候,发现有重复点,那么在T1里删去深度大的那个,查询直接在T1里区间求和即可。复杂度不会计算,陈老师说是nlogn