自闭集训 Day5

树上数据结构

前置知识

  • 点分治
  • 边分治
  • 树链剖分
  • LCT
  • Top Tree

LCT时间复杂度

线段树每次查询是严格\(\log n\)的,然而splay维护连续段的时候,如果每次查询可以缩点,那么访问的区间数是均摊\(O(1)\)的。(??)

所以用splay维护LCT是一个log,而线段树维护就是两个log。

捉迷藏

边分治多好,干什么点分治……

每个点开个堆维护子树最远点、开个堆维护儿子最远点的前二大的值、开个堆维护全局最大值,然后随便搞。

边分治由于每次只需要合并两个子树,所以好写很多。

bzoj2566

每个颜色分别维护。

bzoj3730

每个点树状数组维护距离为\(len\)的点权和,然后暴跳点分树。

为什么可以树状数组?最大\(dep\)小于等于子树大小,而点分治的子树大小之和为\(n\log n\)。

幻想乡战略游戏

见博客。

Ynoi2011 D1T3

回滚莫队+线段树合并,不过可能假了。

每次查询的时候找到点分树上最浅的点,使得它在连通快内,然后把它看做根来做。

然后考虑一个点\(i\),如果\(i\)到根的\(min,max\)都在\([l,r]\)内,那么\(i\)就在连通快内。这是一个类似于二维数点的东西。

然后再带上颜色的限制,就是一个类似于三维数点的东西。

对每一个点都预处理上面的东西,离线一下,就是\(O(n\log^2 n)\)了。

floj307/CF1010F

先考虑\(O(n^2 )​\)做法,发现就是一个很无脑的DP:设\(f_{x,i}​\)表示考虑\(x​\)的子树,搞到\(i​\)大小的连通块的方案数,然后乱搞。用生成函数表示就是\(f_x=x\prod (f_v+1)​\)。

链剖加速,每个轻儿子的大小之和是\(n\log n\),一条一条重链来做。

设\(F_ i( x)\)表示考虑重儿子的生成函数,\(A_i(x)\)表示不考虑重儿子的生成函数。

那么有\(F_i(x)=(F_{i-1}(x)+1)A_i(x)x\) ,分治FFT。

似乎是把式子展开之后就是\(\sum\limits _{i=1}^n \prod\limits_{j=i}^n B_j\),发现可以分治FFT搞起来,就没了。

Ynoi2011 D2T3

可以根号分治,注意修改的时候只会有\(O(\sqrt{n})\)个点旁边有大点,所以可以暴力。

链分治,每个点只维护轻儿子,然后修改的时候就只需要修改重链头的数据结构,于是\(O(n\log^2 n)\)。

每次只维护轻儿子应该是个套路。

UOJ191

把操作树建出来,加点就是往儿子走,删点就是跳父亲,查询就是询问某条链上的最大值。

答案显然是在上凸壳上,现在问题是如何维护凸壳。

最naive的方法是树链剖分,然后每条重链用线段树维护凸壳,这样是\(O(n\log^3 n)\) 的。注意横坐标没有单调性,需要用平衡树维护。

发现跳重链有一个性质:只要当前重链不是最后一条,那么要查询的点必然是一个前缀。

既然是前缀那么就可以离线,然后每条重链上面分别做,可以一个\(\log\)。

所以最后总复杂度就是\(O(n\log^2 n)\)。

某题

两个操作:修改点权、求最大权值连通块。

就是个动态DP,直接搞。

LCT

由于LCT的access是均摊的,所以不能可持久化。

然而有严格单次\(\log n\)的动态树,然而不会。

某题

可以用\(a_i\)的代价选中子树中所有叶子,问把\(x\)子树中的叶子选中的最小代价。

有一个简单的暴力DP:\(f_x=\min(a_x,\sum f_v)\)。

重链剖分,转移方程变为\(f_i=\min(a_i,f_{i+1}+b_i)\)。

把这个看做是一个变换\((a,b)\)表示\(x\rightarrow \min(a,x+b)\),然后发现这个变换可以合并:
\[
\min(c,\min(a,x+b)+d)=\min(\min(c,a+d),x+b+d)
\]
而且显然还支持结合律,所以可以线段树维护。套上树链剖分之后就\(O(n\log^2 n)\) 了。

如果用LCT维护,那么由于有reverse操作的存在,要额外记录反过来变换的值,稍微难写一点,但复杂度是\(O(n\log n)\)。

某题

设\(dp_{i,x}\)表示到了\(i\)的时候值为\(x\),胜者是谁,然后从右往左DP,发现每次只会改一个位置的值,于是获得了\(O(qn)\)的做法。这个做法不怎么能优化……

发现一个性质:每次游戏只会有最多一个人动手,并且动手之后必然会搞成自己的编号。

所以前\(i\)个人只会搞出小于等于\(i\)的数。

然后连边:\(i\)朝\((i-a_i)\% n\)连边。如果\((i-a_i)\% n\ge i\)那么不用连。

这样形成了一个森林。

那么考虑一个DP:设\(dp_{x}\)表示如果走到了\(fa_x\)那么\(x\)会不会改。如果儿子里有一个是1那么自己就是0,否则就是1。

最后考虑0,如果\(dp_0=1\)那么0赢了,否则就是0的儿子里面是1的编号最小的点赢了。

考虑修改操作,发现就是个动态DP,用LCT维护。

CodeChef Pushflow

最大流就是最小割,最小割要么切树边要么切两条环边。

如果切环边,那么肯定要切最小值,所以可以直接把最小值丢掉,加到其他边上。

也可以用圆方树直接搞,我可能白学了圆方树……

WineDAG's prevention

一个树,增加点的点权、翻转一条路径上的权值、询问路径最大值、最小值。

正常LCT是做不了的,因为LCT内的splay是按深度为权值的。

这题可以维护两棵splay,一个是形态splay,另一个是权值splay,用中序遍历的序列来一一对应。

于是修改就可以直接在权值splay上面翻转而不改变树形态,于是做完了。

CF1137F

根本不会 /kk

什么时候\(x\)在\(y\)之前被删除?令权值最大的点为根,当且仅当\(x\)不是\(y\)的祖先,并且\(x\)的子树最大值不超过\(y\)的子树最大值。

每个点记录每个儿子到父亲节点的权值。

那么一次up操作会发生什么?相当于一次换根+链覆盖。链覆盖可以看成是LCT的access操作。

于是对于LCT里面每一棵splay,维护它的权值在全局的rank,然后查询的时候就先看这个点所在的splay的rank,再加上自己在splay中的位置。

某题

给三个点集\(A,B,C\),满足\(AB,BC\)都构成一棵树,\(A\)内部没有连边。

问随机\(i,j\)把\(B\)中编号小于等于\(i\)的、\(C\)中编号小于等于\(j\)的点删掉,\(A\)仍然连通的概率。

从大到小枚举\(i\),看最大的\(j\)使得仍然连通。显然有单调性,于是可以two pointers。

怎么判断呢?

假设枚举了\(i\)之后把\(C\)中的点挨个删掉,求最晚的连通的时刻。考虑连通性是由某棵生成树撑起来的,所以我们只需要维护删除时刻的最大生成树。

那么从后往前枚举\(i\)的时候会不断地加一些不会被删除的边,即权值为\(\infty\)的边,然后LCT乱搞即可。

2019暑期金华集训 Day5 树上数据结构的更多相关文章

  1. 2019暑期金华集训 Day5 生成函数

    自闭集训 Day5 生成函数 一般生成函数 无脑地把序列变成多项式: \[ \{a_i\}\rightarrow A(x)=\sum_{n} a_nx^n \] 形式幂级数 生成函数是一种形式幂级数. ...

  2. 2019暑期金华集训 Day1 数据结构

    自闭集训 Day1 数据结构 CF643G 用类似于下面的方法,搬到线段树上. 如何合并两个集合?先全部放在一起,每次删掉最小的\(cnt_i\),然后把其他所有的\(cnt\)都减去\(cnt_i\ ...

  3. 2019暑期金华集训 Day6 计算几何

    自闭集训 Day6 计算几何 内积 内积不等式: \[ (A,B)^2\le (A,A)(B,B) \] 其中\((A,B)\)表示\(A\cdot B\). (好像是废话?) 叉积 \[ A\tim ...

  4. 2019暑期金华集训 Day7 分治

    自闭集训 Day7 分治 主定理 由于我沉迷调题,这个地方没听课. 某些不等式 咕了 nth_element 使用快速排序的思想,选一个中间点,看左右有多少个. 期望复杂度\(O(n)\). 首先把一 ...

  5. 2019暑期金华集训 Day7 动态规划

    自闭集训 Day7 动态规划 LOJ6395 首先发现这个树的形态没啥用,只需要保证度数之和是\(2n-2\)且度数大于0即可. 然后设\(dp_{i,j}\)表示前\(i\)个点用了\(j\)个度数 ...

  6. 2019暑期金华集训 Day3 字符串

    自闭集训 Day3 字符串 SAM 考虑后缀树. SAM的parent树是反串的后缀树,所以后面加一个字符的时候相当于往串前面加一个字符,恰好多出了一个后缀. 于是可以以此来理解SAM. 每一条路径对 ...

  7. 2019暑期金华集训 Day3 图论

    自闭集训 Day3 图论 NOI2019 D2T1 没有真正建出图来的必要,可以直接打取\(\min\)的\(tag\). 也可以把边压进堆里,然后变成一个二维清点问题(???),然后就线段树+并查集 ...

  8. 2019暑期金华集训 Day6 杂题选讲

    自闭集训 Day6 杂题选讲 CF round 469 E 发现一个数不可能取两次,因为1,1不如1,2. 发现不可能选一个数的正负,因为1,-1不如1,-2. hihoCoder挑战赛29 D 设\ ...

  9. 2019暑期金华集训 Day2 线性代数

    自闭集训 Day2 线性代数 高斯消元 做实数时,需要找绝对值最大的作为主元,以获取更高精度. 在欧几里得环(简单例子是模合数)意义下也是对的.比如模合数意义下可以使用辗转相除法消元. 欧几里得环:对 ...

随机推荐

  1. Springboot 结合百度IORC实现自定义模板图片识别

    前言: 首先呢,最近再公司的项目当中遇到这样的一个问题,就是需要识别图片,提取图片当中的关键语句,而且识别的语句当然是人家手写体识别,翻来覆去一想,最终还是决定使用百度的OCR帮助我解决这一项需求 话 ...

  2. Unity的学习笔记(UGUI文本逐个字输出)

    之前在网上找过各种的逐个输出字,我可能理解能力不好,照着代码复制没有能使用成功,于是自己研究了很多网上说的思路,各种改良出了一个能用的,写完自己测试,觉得还真好用,于是记录下来 用法:将用代码组件挂上 ...

  3. BUAAOO-Final-Summary

    目录 总结本单元两次作业的架构设计 总结自己在四个单元中架构设计及OO方法理解的演进 总结自己在四个单元中测试理解与实践的演进 总结自己的课程收获 立足于自己的体会给课程提三个具体改进建议 两次架构设 ...

  4. error LNK2005: “找到一个或多个多重定义的符号” 已经在 xxxx.obj 中定义 的解决方法

    1 问题还原 这里我有三个源文件:Base.hpp, Base.cpp 和 main.cpp 在Base.hpp里面定义一个基类,注意,基类只包含构造函数和析构函数的声明,函数在Base.cpp里实现 ...

  5. 怎样用 vue-i18n这个结合vue的$t来实现通过data传值的翻译

    <el-row class="searchForm"> <template v-for="(item,index) in searchConfig&qu ...

  6. JavaScript之变量提升

    变量提升:在JavaScript中,页面加载时,会将用var声明的变量提升到作用域的最前端,只能提升声明,不能提升赋值 如果变量先赋值再使用,可以省略关键字var 如果先使用变量,再赋值,不可以省略关 ...

  7. JavaScript之运算符

    (1)赋值运算符 // c+=1; // 相当于c=c+1; // console.log(a++); // 先将a的值赋值给表达式,a再加1 // console.log(++a); // a先加1 ...

  8. 【雅思】【绿宝书错词本】List25~36

    List 25 ❤arable a.可耕作的 n.耕地 ❤congested a.拥挤不堪的:充塞的 ❤split v.(使)分裂,分离:(被)撕裂:裂开:劈开:分担,分享n.裂口:分化 ,分裂 ❤n ...

  9. Jmeter学习笔记(十四)——逻辑控制器

    一.逻辑控制器简单介绍 Jmeter中逻辑控制器(Logic Controllers)的作用域只对其子节点的sampler有效,作用是控制采样器的执行顺序.放在逻辑控制器下面的所有的采样器都会当做一个 ...

  10. SIM900 HTTP POST

    AT+SAPBR=3,1,"CONTYPE","GPRS" OK AT+SAPBR=3,1,"APN","CMNET" ...