• 树分块 学习笔记


    树分块有两种方法:
    1."王室联邦"分块:
    一个点可以在多个块中。
    每个块有一个顶部,每个块只能和其它块共用顶部。
    一个块的顶部是它的所有点的lca,顶部深度最小。
    每个块的深度次小的节点的父亲相同,都是块顶。
    对于每个块,如果插入每个块的顶部,则块内每个节点必须连通。
    删除所有块的顶部,最多只有1个块的大小不在范围([B,3B])之间。
    分块方法:用栈和dfs,在dfs的过程中维护数组sz,表示当前和点(x)连通的,还未被分块的节点个数。
    栈是未被分块节点集合。
    (szgeq B)时,把栈中所有节点删除,给这些节点新分配一个块。
    事实上,这样子分块后每个块也能构成树结构:把每个块新建一个点,每个块的顶部也建一个节点。
    每个块顶和每个块对应的节点连边。
    如果(a)块和(b)块有公共点但是块顶不同,则连边。
    块顶为(x)
    2.随机分块
    在树上随机取(B)个关键点。
    把关键点和根建立虚树。
    虚树上的点就是关键点。
    这个分块的性质是:一个点期望向父亲跳(frac{n}{B})次就能遇到关键点。
    它在处理路径信息比较方便。

    随机分块:
    问题1:树上路径众数。
    先把询问的((x,y))向跳到上面第一个关键点((x',y'))
    如果(x'=y'),则可以暴力跳跃。
    否则考虑((x',y'))路径上的众数,可以把所有关键点为根求出。
    根据分块的一种方法(空间(nsqrt{n})),可以考虑预处理出(f_{i,j})表示第(i)个关键点到根的节点有多少个(j)
    (f_{x',a_i}+f_{y',a_i}-f_{lca(x',y'),a_i})即可求出路径上的颜色为(a_i)的点数。
    时空复杂度(O(nsqrt{n}))

    问题2:lg3603

    链上显然可以分块,预处理每个块的bitset,查询时把对应块的bitset or起来后,对于边角暴力修改即可得到答案的bitset。
    然后find_next即可。
    树上显然可以树分块
    随机分块后预处理关键点之间的bitset,查询把对应块的bitset or起来后,对于边角暴力修改即可得到答案的bitset。

    问题3:IOI2009 regions

    问题4:loj6115

    问题5:hdu6271

    简单题
    随机分块后,考虑每个询问点跳到它的上面第一个关键点。
    设询问((x,y))为插入根到((x,y))边的连通块个数
    设一个询问跳到((x',y'))
    则从((x',y'))向下插入(sqrt{n})条边就可以得到答案,然后撤销即可。
    用并查集维护。
    我们还需要维护插入根到((x',y'))边的连通性。
    固定(y'),从根到(x')dfs。
    在dfs到某个点时维护这个点到父亲的边集即可。

    王室联邦分块:
    问题6:gty的妹子树
    做法1:时间分块(定期重构)
    做法很显然。
    (sqrt{n})个0/2操作后重构
    如果没有修改,显然用可持久化线段树合并,查询子树中(<a_x)的值即可。
    如果有修改,发现如果更新可持久化线段树需要全局更新。
    如果不全局更新,考虑记录下所有被修改过的点,这些点显然不多。
    对于0操作我们需要查询子树/父亲链对当前点的贡献,然后减去原来的贡献,加上现在的贡献,而2操作就不用
    最多只需要扫描(sqrt{n})个点。
    快速判定一个点是否是另一个点的祖先可以dfs序,然而重构后不能用dfs序。
    考虑倍增,设要判定(x)是否是(y)的祖先,显然把(y)跳到和(x)同深度后,判定(x)是否等于(y)即可。
    时间复杂度(O(nsqrt{nlog_2n}))

    问题7:「THUPC 2019」不用找的树

    问题8:count

    先考虑序列上怎么做。
    (O(n^2))做法:(a_j-a_i=a_k-a_j),可以枚举(j,k)(i)必须(<j)
    这样子由(j,k)可以得到(i)的值:(2a_j-a_k=a_i)
    维护桶即可。
    优化显然考虑分块,注意到(j,k)在同一个块内时间复杂度较低。
    分4种情况:
    1.(i,j,k)在同一块:枚举(j,k),维护(<j)下标构成的桶
    2.(i)在某一块,(j,k)在另一块:(j,k)最多枚举(O(nsqrt{n}))次。
    3.(i,j)在同一块,(k)在某一块:同情况2
    4.(i,j,k)分别在不同的块内:此时(2a_j=a_k+a_i)
    事实上,可以对于两边块内的所有元素的对应位置(cnt_{a_i}++),两边fft卷积即可。
    考虑拓展到树上。
    分块后

    问题9:lg5064

    问他10:rpdq

  • 相关阅读:
    linux可执行文件添加到PATH环境变量的方法
    PHPExcel所遇到问题的知识点总结
    如何查看已经安装的nginx、apache、mysql和php的编译参数
    oracle 创建用户及表空间命令
    datetimepicker 设置日期格式、初始化
    Linux 修改系统时间(自动同步)
    Nginx 负载均衡配置
    CenterOS7 安装 Nginx【转】
    java https post请求并忽略证书,参数放在body中
    将.cer证书导入java密钥库?
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14707339.html
Copyright © 2020-2023  润新知