竞赛日记 1.14-3.26
作者:互联网
2020 竞赛日记
目的是总结没有来得及写完的题目中蕴含的idea以及梳理每日所学。
Jan.
14
- 成功地换上了\(Ubuntu19.10\) 心情一颗赛艇
还是我太naive了真·对\(Ubuntu\)一见钟情,太好用了趴。 立志精通\(Ubuntu\) - 集训队\(dalao\)安博施讲题 主题是
并不简单DP。
DP杂题 \(I\)
- [x] \(CF372B\ Counting \ Rectangles\ is \ fun\)
题目本质上是求四维偏序。先描述一个矩阵,处理成一个仅带有0和1的四维矩阵,再告诉你一个四元组 \(<ai,bi,ci,di>\),求解\(i,j,k,l(i<=k,j<=l)\)满足
\[\begin{cases} \ i \ge \ ai \\ \ j \ge \ bi \\ \ k \le \ ci \\ \ l \le \ di \\ \ f[i][j][k][l] = 1 \end{cases} \]
的总方案数。考虑到类似这样的二元组\(<ai,bi>\)描述的是一个无限扩展的平面,把每个\(f(i,j)=1\)的点投影到整个平面中,如此,便可\(O(1)\)求出某个点右上方所含的包含\(1\)的点。至于投影,如果需要 \(ai<=i\)则在\(x\)轴上作后缀和,反之作前缀和[1]。这个东西的名字叫偏序,二维的叫做二维偏序,四维则叫做四维偏序。
- [x] P3746 组合数问题
组合数本身的性质适合递推,考虑到每个物品只有选与不选两种,设计方程\(f(i,j)=f(i-1,j)+f(i-1,j-1)\)。矩阵加速并滚掉\(i\)维度即可。
- [ ] P2519 \(Problem\ a\)
可将题目转化为选取任意个带权集合,各个集合没有交集,使得最终的权值最大。
- [ ] P3188 梦幻岛宝珠
大致是利用二进制,对于每一个\(a\)对前面的\(a\)做一遍背包,再将所有背包根据一点奇技淫巧合并即可。合并蕴含了贪心的思想。
- 上课的时候与 $ wyx\ wey\ hkh\ wyc\ lys\ zjy$ 一起讨论出了课堂上的很多题目。有时候真是人多力量大,某个人可能想到了这个思路但没深入想便放弃了,但如果讲出想法没准就有人可以顺着思路想优化。默契×10086 !
- 学习了\(LateX\)的一点皮毛。\(LateX\)着实好用,用来表达一些公式关系之类的再好不过了。
15
“\(AC\)自动机这个东西不难,现学现用嘛。”
“二项式反演很简单的,知道\(f(i)\)推\(h(i)\)很简便的。”
—— \(dalao\) 安博施
“机房就是一个摩尔庄园。”
—— \(Imakf\)
- 今天也是安博施讲课。如果说昨天是
并不简单DP的话,那今天就是魔鬼DP了AC自动机容斥原理树上斜优警告真的还有好多东西不会。思维也完全跟不上,讲的东西只能意识跟着走,一时半会根本想不出来代码怎么实现。
DP杂题 \(II\)
-
[ ] ~$ K\ perm\ counting$
将一个序列横着写一遍纵着写一遍形成一个方阵后,每个排列就可以对应方阵中的一行\(0/1\),加上\(\neq k\)的条件可以看成是给方阵画 \(y=x\pm k\) 的图像,再将横/纵坐标相同的所得的点连起来形成一根链,这样可以得到若干条链,要求链上的任意两点不相邻。在若干条链上DP即可。
-
[ ] $ BZOJ4361 \ isn$
-
[ ] \(P3349\) 小星星
-
[ ] \(P4728\) 双递增序列
-
[ ] \(P3311\) 数数
-
[ ] \(BZOJ1767\ harbingers\)
-
今天复习了一下树形DP,在DP1上也写了两个题。希望自己能重新回顾DP1和DP2,按计划在放假的十几天内把这十几天来布置的题目认真做完总结好。尤其是DP2,多训练思维。
16
“期望的本质是积分。” —— \(Imakf\)
“信息学最重要的是数学基础。” —— \(ysuperman\)
“期望可以代表整体。如果这串数随机选一个期望为\(k\),你就认为每次选择都是\(k\)。”
—— \(lightmain\)
-
早上罕见地 \(7:30\) 才起床 还下了点小雨
预示今天的悲惨?? -
上午讲解概率和期望。
概率期望 概念
-
[ ] 概率分为古典概型和几何概型。古典概型结果有限,几何概型结果无限。古典概型和几何概型中每个基本事件的发生概率均相同。任意两个基本事件互斥。
-
[ ] 互斥事件:如果事件\(A\)与事件\(B\)不能同时发生,则称事件\(A\)与事件\(B\)互斥。
对立事件:如果事件\(A\)与事件\(B\)必有且仅有一个发生,则称事件\(A\)与事件\(B\)对立。
独立事件:如果事件\(A\)与事件\(B\)相互没有影响,则称事件\(A\)与事件\(B\)相互独立。
-
[ ] 性质:互斥事件任一发生可加,独立事件同时发生可乘。
即 \(P(A \cup B)=P(A)+P(B)\ \ P(A \cap B)=P(A)*P(B)\)
-
[ ] 全概率公式:$P(A)=\sum _{i=1}^n{F(Bi)*P(Bi)} $ \(F(x)\)表示\(x\)在\(A\)中的比例
全期望公式:\(E(A)=\sum_{i=1}^n E(Bi)*P(Bi)\)
-
[ ] 几何概型一般转化成坐标系考虑。随机变量就是维度,坐标系中的点对应一个基本事件,满足条件的事件(点)所组成的a度量(面积/体积等)与总度量的比为满足条件的事件的发生概率。
-
[ ] 在区间\((a,b)\)中等概率选择一个实数,其为有理数的概率是 \(1\),为无理数的概率也是 \(1\) 。即概率为 \(1\) 的事件不一定是必然事件。
概率期望 例题 [2][3]
- [ ] 在\((0,1)\)内任取两个数\(a、b\),\(|a-b|>=0.5\)的概率为\(\_\_\_\),\(a^2-b>=0\)的概率为\(\_\_\_\),\(a^2+b^2<=1\)的概率为\(\_\_\_\)。
- [ ] 把木棍砍成三截,能拼成三角形的概率为\(\_\_\_\)。
- [ ] 正实数范围内任意选三个数,能拼成三角形的概率为\(\_\_\_\)。
- [ ] 给定一个\(2*2\)的方阵,初始时位于左上角,每次随机走向一个相邻的格子,则走到右下角的期望时间为\(\_\_\_\)。
- [ ] 长度为 1 的线段上随机取两个点,则以这两个点为端点的线段的期望长度为\(\_\_\_\)。
- [ ] 圆内任意取四个点,则四个点在同一半圆的概率为\(\_\_\_\)。
- 中午天气难得放晴
预示下午状态转好?? - 下午讲解概率DP
说是概率,设状态90%都是期望QAQ
概率DP
-
[x] \(P5014\) 红包发红包
在一堆数字中等概率取数,可以把每次取数都简单地看成是取了期望值。大数定律告诉我们,在随机事件的大量重复出现中,往往呈现几乎必然的规律,而这个必然的值就是期望。所以可以简单认为单次选择必然选中期望值。
( 口糊数学证明??) -
[ ] \(CF1245E\ Hyakugoku\ and\ Ladders\)
-
[ ] \(P1291\) 百事世界杯之旅
-
[ ] \(CF24D\ Broken\ robot\)
高斯消元。
-
[ ] \(P3232\) 游走
-
今天上午感觉不是很好,可能是由于本身概率期望的概念就没搞得很清楚,就引入了微积分。学东西还是要首先把握最核心的,最基本的,再去创新,再去与别的东西融会贯通。课堂上讲的一些题目非常经典,抄到了日记上,以后要多多温习、领会。经过中午把概念理清楚,下午听课就好多了。
-
真·我还是太弱了。\(Imakf\) 大佬讲到排列组合会排列组合,讲到概率期望会概率期望,讲到高斯消元会高斯消元,讲到微积分连微积分也会,而且都是能拿来做难题的层次。平心而论,我的数学基础还是有些薄弱。多理解,多做题,多去看看书,不会的就问。希望以后至少达到碰到常规上的排列组合啊之类的可以轻松做出来的层次吧。
-
今天写了一道计数题,自己手推,受益匪浅。数学题一定要多做,练出感觉来。DP1也写了1道题。DP1的题目还是挺有嚼头的,争取\(AK\)!
-
调试数据太弱一直是我的缺点。整理一下方法?
如何设计有强度的调试数据
- [ ] $0\ /\ 1/\ $负数
- [ ] 数列中含有重复数字
- [ ] 题目设定的极限数据
- [ ] 多模字符串匹配问题中相同的模式串
17
“人生就像动态规划,你的一个又一个阶段是由上天安排的,而你,决定的是在这一阶段可以由上一阶段的哪些状态转移而来。越勤奋,越幸运,并不代表这一次你决策的方向有多么优秀,却代表着现在的这一个状态能够续写多少可能的结果。”
- 上午,信息组与生物组联谊去隆平科技园做实践活动。博物馆中看到了很多专业的生物知识,或许放在小学初中我就当看看就过去了,但我今天确能看懂许多东西了。所谓的“三系法”等等经生物组巨佬 \(ljw\) 讲解也大概搞清楚了。知识的确可以改变一个人的许多,包括看待事物的心态,学习知识的速度等。蛤蛤 \(ovo\)。
好像与竞赛内容无关,算辽
-
下午写了一道数位DP。
大概是我没看题解切的第三道数位DP??现在数位DP的感觉还不错,普通的数位DP可以纯凭一己之力想出来了。但比较难的,创新一点的题就是个未知数了。 -
晚上华精聚会。
-
\(22:30\) ~ \(24:00\) 可能是我搞竞赛的主力时间(哭)。很开心,DP1除了那道容斥原理的题,其余都写了。DP1的题目确很有意思,值得一刷。
-
[x] \(Blocks\)
区间DP。关键是如何设置状态。题目难点在于每一段区间内我们应该分成多少段合并。枚举分成多少段是 \(2^n\) 级别的,显然不可做。考虑到其实这 \(2^n\) 中,我们其实又有大量冗余的计算,对于\(r\)后面剩了相同数量同种颜色的状态,我们是可以合并的。于是问题可做了。
18 小年快乐
“\(Oh,my\ sweet \ summer\ child,what\ do\ you\ know\ about\ fear\ ?\)”
"生于夏季的小可爱啊,你又知道什么是危险吗\(?\)"
——《权力的游戏》
- 上午做树形DP。成功AK了树形DP。
- [x] \(P2279\) 消防局的设立
首先应区分好选择某点与覆盖某点的不同。看题解前本题给我的一个困扰是如何处理兄弟节点相互覆盖的问题。题解是在父亲节点处处理兄弟节点互相覆盖的问题。而实现这个转变只需要考虑每个节点覆盖到向上\(x\)层的最优方案就可以了。
- [x] \(POJ2486\ Apple\ Tree\)
本题的难点在于我们不能确定一棵子树究竟是走到底还是走回来。而这个问题的关键又在于最后是否回到子树的根,而非经过子树的根几次。一定要把握住问题的关键去设方程。
- 下午只想着放假,无心学习。跟着 \(zzt\) 学习了一下怎么装 \(ubuntu\) 。貌似回家路上我还满怀希望呢。
- 晚上,安装 \(ubuntu\) 失败。整个晚上,一事无成。被家里电脑整疯了。欲语泪先流。
19
-
昨天的自己不像自己啊。或者说不像我心目当中的自己吧。为了装一个 \(ubuntu\) 真就荒废了一个晚上呢。也许这是我的一个顽疾吧,放假的时候心总是立刻就散漫了,总是想着像以前小学那样,一颓一上午甚至是一天。今天没做多少常规作业,\(CF\) 的比赛没有坚持,\(vjudge\) 上的题目也没做。效率极低。你要记住你现在还很菜呢。该改变的时候就不要犹豫吧。
-
状压DP告一段落。
-
[x] \(P2831\) 愤怒的小鸟
-
啊李庚希真是太漂亮辽。
20
-
数位DP告一段落。
-
[x] \(HDU4507\) 吉哥系列故事——恨7不成妻
题目的难点在于如何实现平方和的递推。考虑到每一次求解平方和时:\(ans(now)=\sum_ {i=0}^{up}ans(i)\) ,而\(ans(i)=i^2*\sum_{i'=0}^{up'} num(i')+\sum_{i'=0}^{up'} ans(i')+2*i*\sum_{i'=0}^{up'}sum(i')\)(其实也很好理解,就是完全平方式的展开公式,由于是累加所以带个\(\sum\))所以每次记录下\(num(i)\)符合条件的数字个数、\(sum(i)\)符合条件的数字和以及\(ans(i)\)符合条件的数字的平方和即可实现递推。
- [x] \(POJ3208\ Apocalypse\ Someday\)
二分+数位DP。
21
-
之前做的题目量看上去很多,但实际上都是那一类里面最简单的几个题。要啃硬骨头!尤其是培训之间学的模模糊糊过去的知识点(斜率优化 四边形 DP杂题等等)要多练习。
-
[x] \(P3303\) 淘金
一道小技巧很多,非常优秀的题。首先考虑一维情况下,所有变换后有金子的格子上的数字\(x\)一定可以写成\(2^a * 3^b * 5^c * 7^d\)的形式。于是将n以内的这样的数离散化,对每个数作一遍数位DP,看看它能由多少数字转移过来(记为\(c(i)\))即可。二维的答案就是\(c(x)*c(y)\)。处理出前\(k\)大也需要技巧,可以利用大根推来维护。
- [x] \(P3195\) 玩具装箱
- [x] \(P2120\) 仓库建设
两道斜率优化模板题。斜率优化注重式子的变形,在变形过程中可以自己定义大量参数来简化过程,但在打代码时一定要注意自己定义的参数在\(0\)处的初始化。
23
- 开始写数据结构了。
- [x] \(POJ1733\ Parity\ Game\)
关系并查集。区间\([l,r]\)的奇偶性不好转移,记前缀和为\(S(i)\),则区间\([l,r]\)的奇偶性实际上就是\(s[l-1]\)与\(s[r]\)的关系。据此建立关系并查集即可。
- 对于线段树的模板不够熟练,要多敲。向\(yxt\)学习,以后每天一遍。
25 大年初一
"\(POJ\)的题目都好难。"
——罗艺翔
-
哈哈哈哈关系缓和了\(QAQ\)。
-
今日线段树:WA;错因:标记下传时没有上传值;区间修改时没有标记下传。
-
继续做\(DataStructure\)的题目
-
[x] \(POJ2182\ Lost\ Cows\)
思维题。重点是要发现当倒叙遍历时,\(Ai+1\)就是当前位置上的数字在剩余的数字中的排名。值域线段树维护就可以啦。
- [x] \(POJ1151\ Atlantis\)
扫描线的思路挺好想的,重点是如何维护线段树。可以这样考虑:每个区间有一个标记,如果标记\(>0\),则整个区间都被覆盖,反之,则该区间被覆盖的部分由左边被覆盖的和右边被覆盖的组成。据此维护线段树即可。还应注意这个方法没加标记下传,是有局限性的,不可随意推广。
- 加油!明后两天正面刚平衡树!
26
- 今日线段树:WA;错因:数组类型没开\(longlong\)。
27
- 今日线段树:AC!官宣我与线段树!
28
- 平衡树终于打过了!明天开始争取每日一遍平衡树+线段树!
平衡树 \(Treap\)
-
[ ] 本质:带旋二叉搜索树。
-
[ ] 基本功能:\(Insert、Delete、Get\_val、Get\_rank\)。
-
[ ] 核心思想:旋转不会改变\(BST\)的性质,但可以改变堆的性质,且旋转只改变了当前节点与其父节点的堆的性质。故对于一个满足\(BST\)性质但不满足堆性质的树一定可以通过旋转使其成为\(Treap\)。
-
于是顺便用平衡树做了几个题。
-
[x] \(P3369\) 普通平衡树
-
[x] \(P2234\) 营业额统计
-
还有几个用线段树/并查集做的题,非常经典,重点总结。
-
[x] \(POJ2828\ Buy\ tickets\)
值域线段树好题。首先观察题目发现是插队问题,于是从链表或逆推两个角度去思考。但是由于题目每次询问给的是排名而非值,而排名一直在变化,所以用链表不好做。首先可以发现,当前数\(Ai\)的含义是轮到\(i\)时\(i\)之前有多少人,那么逆推推到\(i\)时,\(i\)之后的已经各就其位了,\(i\)就应该站在第\(Ai\)个空位置上。查询第\(Ai\)个空位置,选择用值域线段树。完结撒花~
- [x] \(SPOJ1716\) 区间在线求最大子段和
求和线段树好题。我首先所想的也是考虑要求前后缀的最大子段,但我没有把它深入去思考,上升到维护的层面。还是思维太局限了 这题给我的最大启示就是同一棵线段树绝不仅仅只能维护一个\(sum\)啊,\(max\)啊,它还可以维护许多东西,只要区间整体的信息是由子区间的信息传递来的,就都可以维护。
- [x] \(POJ2912\ Rochambeau\)
关系并查集好题。先总结一下关系并查集。关系并查集常用于只知道两者之间关系,每个数隶属于哪个集合不确定的题目。常见的题目为各种循环有序集等。每个集合中的元素关系相互确定,且值均以代表元素的值为\(0\)进行计算。不同集合中的元素关系无法确定,但可以通过转化进行合并。本题为关系并查集的变式。枚举法官即可。
29
-
今日线段树:AC。
-
锻炼了一下关系并查集。
-
[x] \(POJ1417\ True\ Liars\)
关系并查集+动态规划。加深了对关系并查集合并时的一点理解:可以看成是数轴上的四个点\((x,y,fx,fy)\),其中\(dis(x,y)=d,dis(x,fx)=val(x),dis(y,fy)=val(y)\),自然\(,dis(fx,fy)=val(x)+d-val(y)\)。
30
-
(扫描线+)线段树的一天。
-
[x] \(POJ3667\ Hotel\)
线段树的灵活运用。注意处理时保留的是最长的连续值的长度,至于求解第一个位置,可以递归时处理。毋需保留。
- [x] \(P1856\ Picture\)
求解平面上\(n\)个矩形的周长交集。显然扫描线+线段树。细节注意:由于求解长度时必然是两个坐标相减,若对于一个\([1,4]\)的区间,其结果由\(x[2]-x[1]+x[3]-x[4]\)转移而来的话显然少了\([2,3]\)这一段,所以每次求解答案时应\(x[r+1]-x[l]\)。查询的一开始时候把右端点\(-1\)就可以啦。
31
区间静态第K大,线段树上持久化。
——沃茨基 · 硕德
被逼的无奈只能拿可持久化开刀了QAQ
- 被可持久化支配的一天。可持久化代码不难打,较其他数据结构模板也较容易理解,但难以实际应用,有必要对此进行总结归纳。
主席树
-
[ ] 本质:有诸多根节点的线段树
-
[ ] 区别:与线段树节点与区间一一对应关系不同,主席树区间可以对应诸多节点。
-
[ ] 核心思想:对于仅有单点修改的线段树,其每次修改的操作只会影响一条链上的点,于是就可以新建一个根记录时间戳,根节点的左右儿子中不包含被修改节点的直接继承上一个时间戳,另一个新建一个节点,递归更新,最大限度的利用了空间。
主席树经典应用
-
[ ] 静态区间单点修改 且树上保存的权值具有可减性;
-
[ ] 访问历史版本。
-
今天数据结构落幕了,回想起\(25\)号,那时候不抓紧的话真的可能一题也没做了QAQ。抓紧时间,对自己更有信心,借着这段时间状态不错认真学信息。
-
[x] \(P3919\) 可持久化数组
可持久化的基础。模板题。
- [x] \(P3834\) 区间第\(k\)大
静态区间第\(k\)大问题模板。首先,现在考虑权值大小问题时学会往平衡树和权值线段树方面去想。其次,平衡树上每个点保留的是区间中的数本身,不具有可减性,而权值线段树上每个点保留的是当前区间内小于等于区间右端点的数的总数,具有可减性。于是考虑可持久化权值线段树解决本题。
- [x] \(P3402\) 可持久化并查集
个人感觉可持久化的题目中最难的一道。首先要明确的是,由于可持久化中只支持单点修改,所以不能够进行路径压缩。其次,在寻找集合的代表节点中,由于我们已经把之前的信息都继承过来了,所以\(f\)数组中一直都是当前节点的父亲点值,而非某一个之后添加的编号。换句话说,\(f\)数组里的值恒小于等于\(n\)。顺便学了带秩合并。
- [x] \(P4735\) 可持久化\(Trie\)树
本质上与之前的很相似。结合题目的区间要求,可以给\(Trie\)树加个\(cnt\),\(cnt\)具有可减性,与之前的可持久化权值线段树就一致了。
- 以后碰到了区间限制的题目也可以考虑可持久化做法啦!!
Feb.
2
-
开始字符串专题了。今明两天主攻\(KMP\ Hash\ Trie\ AC\)自动机。今天重点做\(KMP\)和\(Hash\)。
-
[x] \(POJ1840\ Eqs\)
本来应该是个哈希题的,但我用哈希死活\(TLE\),后来学习网上的用\(short\)过的。 \(excuse\ me\)?!!
- [x] \(POJ1961\ 4\ Numbers\)
与上题一样是个哈希模板,但我用\(vector\)的哈希死活\(TLE\),网上的链表做法可以过,我\(copy\)下来自己造数据跑结果跑的没有我的程序一半快\(qnq\)。心如死灰地抄题解走人。
- [x] \(POJ2406\ Power\ Strings\) & \(POJ2752\ Seek\ The\ Name,Seek\ The\ Fame\) & \(POJ1961\ Periods\)
三个题都揭示了\(KMP\)算法中\(Fail\)数组的其他性质。\(Fail\)数组的本质是前后缀匹配的最大值。先摆结论:假设匹配\(t\)数组,若\(n\%(n-Fail[n])=0\),那么\(t[fail[n]-1,n]\)必然为串\(t\)的最大周期子串。证明很简单,由于\(n\%(n-Fail[n])=0\),所以原串必然可以被分成\(k\)份,每份\(n-Fail[n]\)个。由\(Fail\)数组的定义可知,将最大前缀与最大后缀拎出来比较可以发现第一份必然全等于第二份,第二份必然全等于第三份......以此类推即可得证。同时,按照这个方法对\(Fail[i]\)进行一次,可得到次大周期子串。
- 今天最大的收获莫过于学会了扩展\(KMP\)!
扩展\(KMP\)
-
[ ] 本质:高效求解文本串的每一位与模式串的最大相同前缀。
-
[ ] 与\(KMP\)的区别:\(KMP\)应用上还是不够广泛,局限于字符串匹配问题中。而扩展\(KMP\)应用范围就广泛多了。并且在求解完扩展\(KMP\)问题后字符串匹配问题也迎刃而解。
-
[ ] 核心思想:假定目前已匹配完的文本串最远的的位置为\(Maxp\),与之对应的位置为\(p\),对于文本串的第\(i\)项,我们将与文本串的首项与\(p\)对齐,然后\(i\)及\(i\)之后一直到\(Maxp\)就已经与相对应的模式串对应好了。但我们要求解的是最长前缀,故我们现在要知道对于模式串的某一位与模式串本身的最大前缀。\(Next\)数组闪亮登场。而\(Next\)数组的求解就是模式串自己更新自己的过程。至此,算法大致成型。
-
[ ] 一定要多画图理解。
-
终于把做题记录补完了。哪天抽空我得把\(Typora\)告诉老师。
-
待完成的好题
-
[ ] \(POJ3167\)
-
[ ] \(POJ2185\)
3
- 今天效率不错,学习了很多新东西。感觉这几天随着强度加大我每天的学习也更充实了。
- 看看今天学习的新算法吧\(QAQ\),以后多复习。
\(Manacher\)算法
-
[ ] 基本功能:求解最大回文子串。
-
[ ] 核心思想:类似于扩展\(KMP\),充分利用已求解的信息。假定目前右端点最靠右边的回文子串的右端点为\(R\),中点为\(Mid\),那么对于当前枚举到的第\(i\)项\((i<=R)\),必然有\(p[i]>=min(R-i+1,p[mid*2-i])\),即由于前后关于\(Mid\)对称,则\(i\)可继承\(i\)的对称点信息。再扩展\(p[i]\)并适时更新\(R\)和\(Mid\)即可。
-
用\(Manacher\)做了点题目。
-
[x] \(P3805\ Manacher\)模板题
-
[x] \(P4555\) 最长双回文串
本题的实质是求解两个数组\(L\)和\(R\),满足\(L[i]\)为以\(i\)为左端点的最大回文子串长度,\(R[i]\)为以\(i\)为右端点的最大回文子串长度。我最开始的想法是边\(Manacher\)边更新所有的\(L[i]\)和\(R[i]\),但不幸地\(WA\)掉了,原因诸如这组数据:\(BBABBA\),\(L[5]\)(从1标号)显然是\(5\),然而由于计算\(p[4]\)时\(R\)端点更新为了\(6\),故\(L[5]\)计算错误。之后我就发现:每个\(L[i]\)与\(R[i]\)一定都是由某个\(mid\)推出来的\((i\in[Mid-p[Mid],Mid+p[Mid]])\),再通过递推对目前所有满足条件的\(Mid\)带来的值取\(max\)即可。
\(AC\)自动机
- [ ] 基本功能:高效实现多个模式串与单一文本串的匹配。
- [ ] 核心思想:将多个模式串构建成一棵\(Trie\)树,对每个节点(假定当前节点为\(i\))求解一个\(Fail\)指针,满足\([0,Fail]\)[4]为\([0,i]\)在\(Trie\)树上存在的最长后缀。这样就可以在当前节点失配时快速找到下一个可能满足的位置。\(Fail\)指针的求解:首先第一层的节点的\(Fail\)值必定为\(0\);其次,由于\(Fail\)指针的求解具有层次性(必须先求解深度浅的再求解深度深的),考虑用\(BFS\)暴力搜索;第三,\(Fail(t[u][i])=Fail(t[f[u][i])\),即自己的失配指针为父节点的失配指针的与自己所含字母一致的儿子。
- [ ] 细节注意:对于不存在的儿子节点,由于可能有\(Fail\)指针指向它,为了保证正确性,应使不存在的儿子节点编号直接等于其父亲的\(Fail\)指针的相同儿子的节点编号。
- [ ] 复杂度注意:与文本串匹配时,仅暴力跳\(Fail\)可能会导致复杂度退化为\(O(|S|*|T|)\)。将\(Fail\)指针看成边,可得到一棵\(Fail\)树(节点为字符串),树上任意两点的\(LCA\)为该两点的最长公共后缀。且树上的每个节点均为\(Trie\)树上的某个前缀。暴力跳\(Fail\)其实质就是沿着一根链一直向上跳。至此,优化就很明显了。可以每次只保留每个点的\(ans\),最后拓扑排序,每个点的\(ans\)再加上自己子树的\(\sum ans\)就好了。复杂度为O\((|S|+|T|)\)。
- [ ] 扩展:\(Trie\)图、\(Fail\)树、可持久化。
- 用AC自动机做掉了洛谷上的三个模板。前两个都是普通AC自动机,后一个则需要拓扑排序的优化。
- [x] \(P3808\ AC\)自动机模板
- [x] \(P3796\ AC\)自动机模板加强版
- [x] \(P5357\ AC\)自动机模板数据加强版
后缀数组\(SA\)
- [ ] 基本概念:\(SA[i]\)保存第\(i\)名的后缀的起始位置。
- [ ] 实现原理:倍增+基数排序 (扩展:\(DC3\))
- [ ] 核心思想:\(Rank[i]\)表示当前以\(i\)开头的字符串的排名,与\(SA[i]\)构成映射关系。首先根据每个单个字符排序,得到\(Rank\)数组,即每个位置的关键字。首轮排序完后,我们再把相邻两个\([i,i+1]\)的的\(Rank\)合并。自身的\(Rank\)为第一关键字,其后面的\(Rank\)为第二关键字进行排序。排序完后,第\(i\)位上的关键字是以i为起始位置的后缀的前两个字符的排名,第\(i+2\)位置上的关键字是以\(i\)为起始位置的后缀的前两个字符的排名,这两个一合并,即为以\(i\)为起始位置的后缀的前四个字符的排名。至此,倍增思路应不难想出。由于仅有两个关键字,且关键字范围不大,故所用排序为基数排序。
- 待完成
- [ ] \(P3804\) 后缀自动机 及练习题
- [ ] \(P5496\) 回文自动机 及练习题
- 加油!明天也要像今天一样效率满满哈\(QAQ\)!
4
- 今天的学习状态上午效率不高,但下午看线段树\(PPT\)的时候非常专注,基本上理解了大多数的题目。
但依旧打了2h才出一个题目QAQ,实现能力太差了...
- 上午:树状数组初步。了解树状数组的功能等。
树状数组初步
-
[ ] 基本功能:单点修改区间查询。
-
[ ] 进阶功能:区间修改区间查询(任何只涉及单一变量的具有可减性的连续求和)/求第K大的数、求数K的排名/前驱/后缀等。
-
[ ] 与平衡树的区别:线段树实现平衡树的功能必须要求值域范围比较小。
-
找了几个模板题做。
-
[x] \(POJ2985\) 第\(K\)小集合
-
[x] \(P3372\) 树状数组实现区间修改区间查询
-
[x] \(P1972\) \(HH\)的项链
好题。我一开始的想法是主席树,但发现很难使节点具有可减性。正解是离线算法,将所有的待求解区间排序再处理。在线转离线+排序是个很棒的思路。
-
树状数组还有很多拓展功能今天上午没学,明天上午加油!下午重点完成的线段树。
-
[x] $P4198 $ 楼房重建
较灵活的线段树。启示:线段树上某个区间的值被修改后若会影响到其兄弟节点的值,不要放弃思路,考虑是否能在兄弟节点上继续递归维护,将复杂度做到\(O(log^2n)\)。
- [x] \(P4097\) \(Segment\)
标记永久化的精髓体现。永久化的标记一定是基于整个区间得来的。即当前节点的标记是能覆盖到节点所代表的整个区间的。同时,标记永久化后每个节点的答案就由递归路径上的所有节点决定,而不是它本身的值单一控制了。标记永久化灵活简便,但貌似不可以以此处理所有的标记。使用时要注意。
- [x] \(P3373\) 线段树模板二
经典好题。当要维护两个懒标记(如同时有区间乘法维护\(mul\)和区间加法维护\(add\))时,需自定义一个求答案的方法。重点:先考虑如何求答案,在考虑标记之间如何互相维护。本题中,求解答案既可以一路向下求每一层的\(add×mul\),再加入答案之中;也可以只是求\(\sum add\),最后加上当前节点值。再考虑如何维护。若用第一种方法,则每次新增一个\(add\)时,加入标记的必须是\(add/mul\),\(mul\)则自由维护;而用第二种方法,每次新增一个\(add\)时,加入标记的是\(add×mul\),\(mul\)仍然自由维护。显然,第二种维护避免了实数运算,高下立判。
5
-
今天感觉一天效率都有点低...或许是线段树更高级以后代码量激增导致做题速度变慢了吧。还是要更熟练!
-
[x] \(CF444C\ DZY\ Loves\ Colors\)
线段树经典应用:区间覆盖问题。第一次独立尝试标记永久化写题,但仅对值作了永久化处理,覆盖标记没有任何传递处理。(注:覆盖标记是不能永久化处理的!)这个题目给我一个血淋淋的教训:任何标记,要么永久化处理,要么就下传,总之一定要被传递。
- [x] \(P2572\) 序列操作
区间覆盖问题。思维难度不大,独立思考做出来的。但代码量嘛...\(4kb\)警告...,而且基本上包含了很多基础内容。打完以后觉得自己的线段树实现能力更强了。对了,这个题\(1A\)。
- [x] \(P6055\ Siano\)
区间覆盖问题的变式。题目一个很重要的性质:当第一次对序列排序后,任意时刻序列均有序。对于“削去\(>=\)大于等于\(Limit\)部分”的操作,考虑分为三步实现,首先,二分查找(与性质联系上了!)出第一个大于等于\(Limit\)的点,然后,区间求和\([limit,n]\),最后,区间覆盖\([limit,n]\)。区间求和与区间覆盖可以合并写。性质找到,思路理清后,代码实现就很简单了。注意:由于存在区间求和操作,则每次临时求解区间最大值操作复杂度为\(O(logn)\)。直接维护区间最大值来简化代码和时间复杂度。
- [x] \(P4041\) 奇怪的计算器
\(Siano\)的强化版,再维护一个区间最小值即可。技巧:设定一个\(f\)函数,\(f(x)=k1*x+k2*...+kn\),每次传入不同的\(k\)值,来实现同一函数维护各式各样的乘法加法。\(1A\)
- 总的来说,今天重点突破了区间覆盖类的线段树题目,并且阅读了一篇教线段树卡常及拓展的\(PPT\)。思路大致理解了。先留个坑,以后记得敲。
- [ ] 非递归版线段树
6
-
上午主要练习\(RMQ\)和\(LCA\)问题。整个上午感觉效率不高,\(LCA\)看完基础实现的三种方法后,看了三道例题,但只有两道看懂了,有一道还没有敲。图论太恐怖了\(QAQ\)。
-
[x] \(P1816\) 忠诚(\(RMQ\)模板)
-
[x] \(P3379\) \(LCA\)模板
以往都是用倍增去做,但今天学到了\(RMQ\)做法和\(tarjan(Orz)\)两种方法。尤其是\(tarjan\)做法,在离线情况下可以做到近乎线性的复杂度。 可是我太菜了我写的tarjan比以前写的倍增还慢
- [ ] \(P3320\) 寻宝游戏 (思路懂 对拍\(10000\)能过 但交了就\(WA\))
图论题目有许多技巧,比如本题需要用到结论:树上任意点集的极小连通分量的边权和=按时间戳排序并首位相接后的\(\sum dis(a[i],a[i+1])\),\(dis(i,j)\)表示树上两点的最短路径长度。令\(d(i)\)表示节点i到根节点的路径长度,那么\(dis(i,j)=d(i)+d(j)-2*d(LCA(i,j))\),问题转化为在线求解\(LCA\),大功告成。
- [ ] 严格次小生成树(暂时未写)
思路:用\(Kruskal\)求最小生成树时是根据边权来贪心的,所以有:最小生成树上的两点路径上的边权最大值小于等于连接两点的任意一条非树边。依据这个性质,暴力枚举每条非树边,倍增求出该边上的两个端点树上路径的最大和次大值来更新答案即可。
-
下午和晚上继续学习线段树,感觉不错,一道黑题可以自己有思路,另一道黑题看完题解后思路能够理清楚并且一遍\(AC\)。
-
[x] \(SP1776\) 区间最大子段和
类似于模板题。
- [x] \(SP2916\) 区间最大子段和变式五
枚举情况,拆分区间分类讨论。
- [x] \(SP1557\) 区间最大子段和变式二
线段树好题。题目要求区间最大子段和,且相同的数只算一次。注意到条件:相同的数只算一次,联想到HH的项链那题,在线转离线+询问区间排序,每次询问区间右端点右移时都类似于区间加法。本题亦然。将询问的区间根据右端点由小到大排序逐一处理。令\(last[i]\)表示数字\(i\)出现的上一个位置。维护序列\(s[i]=\sum_{j=i}^{k} a[j]\)(\(k\)为当前外层循环中的原序列中的某个数)(计算\(s[i]\)时相同的数也只算一次),那么一定在某个时候\(s[i]\)求出了区间\([i,j]\)(\(j>i\))的最大子段和。但我们不能只看当前的最大值,因为以前出现过的某个值可能更大,且也是合法的(就相当于某一段没加上来),所以我们维护一个历史最大值。同时,我们还应该维护一个历史最大\(tag\),表示从上次\(pushdown\)到现在的最大的延迟标记(也是相当于如果有一段不够优秀,我们就不加它了)。综上,共维护四个量\(Tag,Max,hMax,hTag\)借以维护\(s[i]\)序列的当前答案就可以了。
-
线段树树状数组专题结束了,但对其的学习还远没有止境。有时间再拓展,再升华。
-
[ ] 树状数组· 图案统计问题
-
[ ] 线段树·泛区间覆盖问题、二维线段树问题、在\(DFS\)序上维护问题、延迟标记合并问题、树套数问题
7
- 今天开始了\(LCT\) 平衡树 点分治 树链剖分专题。然而专题时间还是三天。
加量不加价QAQ(这可能是最可怕的专题??每一个都如雷贯耳就是不会(逃 - 不管怎么难♂ 学习还是要继续的。喜大普奔的是,今天学会了\(Splay\)。它不仅比\(Treap\)功能更强大,也挺好写挺好调的。
平衡树\(Splay\)
-
[ ] 本质:带伸展操作的二叉搜索树。
-
[ ] 核心思想:与\(Treap\)类似,但不再是依靠二叉堆来维持平衡,而是伸展操作——将自己旋转到根的位置,以此来保证平衡。(随机情况下树高为\(logn\))
-
[ ] 双旋:当爷爷父亲自己呈一字形时,需要先旋转父亲,再旋转自己。若只是旋转自己,当旋转到根时最坏情况下树仍为一条链,而双旋可以使父亲与爷爷的父亲两个节点在同一层,保证复杂度。这种优势一定体现在\(4\)层高以上的树。
我才不会说我画一个三个点的树分析半天找不出双旋的好处 -
当然是用\(Splay\)写题目啦。\(Splay\)是真的挺好写的,三个题目两个两\(A\)一个一\(AQAQ\)
-
[x] \(P3369\) 普通平衡树
-
[x] \(P4309\) 最长上升子序列
首先输入方式就暗示我用平衡树写(当然好像权值线段树也可)。然后就是一个简单的线段树优化\(DP\)。
- [x] \(P3391\) 文艺平衡树
区间翻转模板题。当平衡树维护一个序列时,中序遍历即为原本序列,类似查询第\(K\)大就成了查询序列第\(K\)位。\(Splay\)还有一个很好用的性质,就是当要对区间\([l,r]\)操作时,可以将\(l-1\)转到根节点,\(r+1\)转到根节点的幼儿子,这样\([l,r]\)就全都在\(r+1\)的左子树上了,方便操作。区间翻转就是\(r+1\)左子树上的每个节点的左右儿子都互相交换。这题给我的最大启示:平衡树既可维护数列(节点之间有大小关系),也可以维护一个序列(节点之间有对应在原序列中的先后关系),两种维护说白了最后计算答案(排序后的数列或者原序列)都是用中序遍历。而只要是中序遍历,旋转操作就不会改变该树的性质。甚至除被旋转的两点外,其他点的性质都可以不变。(如本题中待旋转点的爷爷旋转时甚至可以不下传标记)。
- 今天看了下点分治,发现其实也没有想象中那么难,但有许多细节需要注意。明天重点突破点分治,再总结。
8
\(——My\ queen,one\ not\ does\ simply\ struggle\ against\ the\ fate.\)
\(——I\ dare\ change\ this\ fate.We\ will\ fight\ valiantly\ to\ the\ last\ Enderman.\)
\(——\)"\(Ender\ Wish\)"
-
\(Enderwish\)的\(BGM\)实在是太好听啦\(QAQ\)。末影女王好帅气!说的每一句话都用最少的字达到最激励人心的效果。好燃!!
-
根据谢超才神仙的README,每日平衡树可以不写多了,但每日要保证一个来练手感。坚持下来!
-
[x] \(P2596\) 书架
题目不难。基本是Splay基本操作组合一下。TLE了一次,本以为Splay写挂了,后来发现是由于数组开小了\(QAQ\)(存在删除节点再添加节点所以要开两倍空间或建一个\(rubbish\)数组)。但平衡树本身还是没有写挂!开心!越练越熟练!
- 今天如约开始点分治专题。
点分治
-
[ ] 核心思想:对于一些问题,我们可以归纳为经过根节点/不经过根节点两类。而不经过根节点的一定经过某个子树的根节点。分治模型初现。若直接分治,复杂度为\(O(T*n)\),显然\(T\)极易退化成\(n\)。所以每次把根节点设为重心,来保证复杂度。
-
[ ] 实现技巧:对于某个子树求重心时,首先需求出子树大小。
(一遍DFS为了简便实现,我们可以记一个\(Part\)变量,表示当前子树大小,则\(Part=size[to[i]]>size[p]?Part'-size[p]:size[to[i]]\)(\(Part'\)为原来的\(Part\))。一定要注意当前节点可能是原重心的父亲节点,这时要特殊处理。 -
于是用点分治
淀粉质做了几个题练手感。 -
[x] \(P3806\) 点分治模板
-
[x] \(P4178\ Tree\)
点分治+树状数组。或者点分治+双指针也可以。
- [x] \(P4149\ Race\)
以后要练习点分治用这题,不要用模板。我最开始的点分治求重心假了,但是过上两题轻轻松松......感谢这一道题把我卡飞了,让我意识到了自己找重心的问题。(特别鸣谢:\(yxt\ (Orz)\)指出我找重心的错误并教会了我真的求重心方法)。
- [x] \(CF293E\ Close\ Vertices\)
点分治+二维偏序。这一题可以说是前几题的综合版。既限制权值最大值,也限制边数最大值。前几题都可以简单的每次找重心求解,但本题只能用容斥方法写点分治了。点分治的容斥,应该算最初级的那种。先\(Calc\)一遍\(p\)值,由于我们其实只需要经过\(p\)点的,那么所有起点终点在同一棵子树里的答案需要减掉。枚举每条边调用一遍\(Calc\),注意此时应加上之前的必经的路径长度和边数。
- 顺便学习了下树上维护\(DFS\)序问题,做了一道主席树+\(DFS\)序。明天多练习几道再一起总结。
- [x] \(P3899\) 谈笑风生
标题好暴力啊QAQ
\(DFS\)序的灵活运用。考虑到难点是处理\(B\)点在\(A\)的子树中的情况,也就是求\(\sum_{i\in subtree A}size[i]\)。\(DFS\)序有一个很好的性质,就是节点\(u\)子树中的每个节点的\(dfn\)值\(\in [dfn[u],dfn[u]+size[u]-1]\)。这东西显然可以用线段树维护。而由于限制深度差不能超过\(k\),所以我们以深度为下标,而只知道深度并不能确定该点是否在子树上,所以我们需对每个点建立一棵完整的线段树——显然,套上可持久化就可以咯。
9
-
\(Ceris\)!\(Abigali\)!\(Rain\)!或许老外做的片不喜欢大团圆结局??女主黑化与男主反目被男主杀死,我最喜欢的末影女王也被\(Gank\)生死未知。好吧,我得承认,比起她们,\(Azura\)才是我的理想型\(QAQ\)。
-
首先自然是每日平衡树啦。
-
[x] \(P4567\) 文本编辑器
感觉不错,写完平衡树后也没怎么调平衡树。但输入数据太坑了\(qnq\),硬是拖了我很久。
- 说好的DFS序当然不能鸽掉啦
咕咕咕但将\(DFS\)序运用到极致的树链剖分自然是重点啦。
树链剖分
-
[ ] 本质:用各种维护序列的数据结构维护处理后的\(DFS\)序。
-
[ ] 核心思想:普通的\(DFS\)序除了子树编号连续外,只能保证子树根后的连续一段为某一条链(\(DFS\)的搜索顺序决定)。显然,我们可以添加优化,使被记录的这条链最长,也就是已知信息更多。自然而然地,我们就引出了重边的概念。并且由于某一条轻边一定连接两条重边,所以我们可以一直跳到根。而在节点跳跃的过程中,某两个点跳到同一根重边上时,就意味着两点均经过了它们的简单路径——非常实用的性质。
-
[ ] 基本操作:子树内的修改查询/两点间的简单路径上的修改查询/树上单点/边修改查询
(水到渠成QAQ -
于是就泡在树链剖分里泡了一天。
-
[x] \(P3384\) 重链剖分 & \(SP375\ Qtree\)
子树内的修改查询/两点间简单路径上的修改查询模板题。
- [x] \(P2146\) 软件包管理器
\(Exciting\)! 可能是蕴含的思维难度不大吧 我看了一会就想到了区间覆盖线段树维护,\(2h\)打完调完交一手直接过了哈哈哈。太开心了。以后做题都要介个样子\(QAQ\),良性循环。
感觉点分治和树链剖分都是模板居多??
- 晚上看了近\(3h\)的杂文和\(LCT\),基本弄懂了\(LCT\),但时间已经不够了。留个坑,明天填上。
- [x] \(LCT\)
10
-
今天是寒假集训
自习的最后一天,首先还是每日平衡树。 -
[x] \(P1486\) 郁闷的出纳员
这道题关键在于如何处理添加和删除操作。区间加法自然是可以的,但有一种更好的办法。当有添加操作,并且每次操作的对象都是整个数列时,我们可以记一个变量\(delta\),加减操作都直接在\(delta\)上进行,那么每次的答案就是\(v+delta\)。注意一点就是把数字插入树中时也要减去当前的\(delta\)。剩余的就是模板了。本题也让我对\(splay\)中的\(Find\)操作有了更深的理解,当存在原数时,\(Find\)返回原数对应的树上结点值;当不存在时,返回原数的前驱或后驱。由于不存在原数,所以大于前驱的所有数大于原数,小于后驱的所有数小于原数。
话说我这个题只用了1.5h就A了 看来韬哥说得对哈 真是越打越熟练
- 不能鸽掉\(LCT\)是\(8\)。
\(LCT\)
- [ ] 本质:森林。对每条实链开一棵\(splay\),用\(splay\)维护森林中的每棵树的实链,以深度作为关键字(维护相对深度),保证中序遍历到的各点深度严格递增。
- [ ] 重点:从大到小总共有四个层次:\(LCT\)森林、森林中的树、树上用\(splay\)维护的实边、\(splay\)的根节点。
- [ ] 层次之间的关系:森林中的各树互不联通;一棵\(splay\)的根节点,由一条轻边指向为当前\(splay\)中中序遍历最靠前的点在原树上的父亲。轻边认父不认子,重边互相记录。每个节点包含且仅包含于一个\(splay\)中(单个节点视为一棵平衡树)。
如下图是森林中的一棵树,图一为原树,图二为加\(splay\)维护后的树。绿框内的树处于同一\(splay\)中。
- [ ] 核心函数:
- \(Access(x)\):将节点\(x\)所在的树的根到节点\(x\)的链变为实链,且起点为根节点,终点为节点\(x\)。实现方法:先将\(splay(x)\)使该点成为所在\(splay\)的根,由于节点x为终点,所以此时直接\(c[x][1]=0\)实现断边,此时\(f[x]\)指向了上一个\(splay\)的某个节点,\(splay\)那个点,再让它的右儿子直接等于此时的\(x\)(认父不认子),既实现了断边有实现了添边。令\(x\)等于当前节点,再往上反复到根节点即可。
- \(Makert(x)\):将节点\(x\)变为所在的树的树根。实现方法:先\(Access(x)\),再\(splay(x)\),此时由于\(x\)深度最大,我们将整个\(splay\)翻转后,\(x\)深度最小,就是原树的根了。为什么可以直接翻转呢?由于其余的\(splay\)维护的是里面各点的相对深度关系,所以其余的\(splay\)都是不变的。譬如图二,我们交换\(A\ E\)两点后,\(G\)所在的\(splay\)显然是不变的。
- \(Findrt(x)\):找到节点\(x\)所在的树的树根。常用于判断连通性。实现方法:先\(Access(x)\),再\(splay(x)\),一路向左找就可以了。建议此时再\(splay(y)\)以保证复杂度。
- \(Split(x,y)\):拉出一条节点\(x\)到节点\(y\)的链。该链上包含且仅包含节点\(x\)到节点\(y\)上的简单路径上的点。实现方法:先\(Makert(x)\),再\(Assert(y)\)。
好显然啊标签:二分,1.14,题目,题意,线段,日记,3.26,可以,节点 来源: https://www.cnblogs.com/parauni-blog/p/12586872.html