2019年9月
一点小记录
好题选讲做题记录
- 「BZOJ2138」stone - Hall定理 + 线段树
- 「UR #5」怎样更有力气 - 并查集
- 「ARC083」F - Collecting Balls - 基环树 + 思维
- 「AGC028」D - Chords - 动态规划 + 计数
- 「AGC012」E - Camel and Oases - 状压dp
- 「CTS2019」重复 - KMP自动机 + 动态规划
- 「CF868E」Policeman and a Tree - 动态规划
- 「AGC035」F - Two Histograms - 容斥
- 「ZJOI2015」地震后的幻想乡 - 概率和期望 + 状压dp
- 「CF1060F」Shrinking Tree - 概率 + 动态规划 + 计数
- 「UOJ #6」懒癌 - 思维 + 结论 + bitset
- 「CTS2019」珍珠 - 生成函数 + NTT + 容斥
9-3
Process
代码能力还是太差,写T4写了一上午。T2、T3根本来不及看
以后还是要合理分配时间。。。
T1
随便搞,我是直接枚举内的数划分...
显然两个数差得越小越好
T2
[计数][容斥] [巧妙]
考虑和连通图计数类似的做法
设表示个点的连通图,每种方案为边数的次幂的答案,表示个点任意图的答案
显然,时就是裸的连通图计数
考虑:
与类似的方法,前面都是一样的,只是最后一坨东西算法不一样
假设枚举出来的个点图的连边方案的边数为集合,个点图的连边方案的边数为集合
那么我们就是要分别枚举中的元素,然后合并起来,即
化下式子:
到这一步就很显然了
继续考虑:
dp式子就不放了
然后考虑求,设
解释一下
时,考虑每条边的贡献,保证它出现,然后其他边随便选或不选的方案
时,对于某个边数为的图,考虑把贡献看成的形式
即枚举图中的两条边,它们两的贡献是,这样就把乘积转化为求和的形式了
讨论一下这两条边是否是同一条边
T3
[基环树] [动态规划] [背包]
首先,对于一条边而言,若被选,则权值为;否则为
那么和这道题一样的转化后,显然是一棵基环树森林,每个基环树上只有可能是两种取值,假设它们为
我们需要求出两种方案,一种的权值和在数轴上正方向最接近,另一种在负方向上最接近
先每个基环树都取权值(较大的),求出来的权值和在的位置
若,则再换小的肯定不会更优
若,则有可能通过把某些换成之后,会减小,且仍
再抽象一下,即现在有若干个的物品(权值为),需要用它们填一个容积为的背包,问最多能填多少
因为权值比较小,重复的物品较多,所以跑多重背包即可
再对每个基环树取权值,做一遍类似操作即可,即从负方向逼近一次
T4
[k-d tree]
我直接写的三维k-d tree
,过了
9-4
Process
三道题都比较简单,没有挂分。要继续保持
T1
我直接用的set+链表
模拟,实际上就是求最长上升子序列的长度
T2
[动态规划] [字符串] [AC自动机]
表示到填第位,从至构成的数等于的方案数
转移的时候注意一下前导0
实际上也可以AC自动机做
T3
直接模拟,用BIT
链加即可
9-5
Process
半个小时写完T1,想了很久的T2,无果,复习了一下SAM之后把T3写了。最后把T2写了个退火,获得了20分的好成绩
dp掌握的不太熟练,要多加练习
T1
[数学]
令,则
等比数列求和即可,比较简单
注意特判公比为的情况!!!
T2
[动态规划] [DP优化]
首先需要注意到,最终的01串中的每一个数字展开(还原后)是一系列不相交的区间!!!
于是可以区间dp,设表示区间,合成的状态为的最大分数
因为区间长度确定,且每次操作后,长度都会减少,因此的位数是确定的
设表示区间长度为时, 最终合成的状态的长度,那么区间dp转移时枚举的需要满足
因此,所有的状态都可以通过若干个的状态合并出来
再优化一下,发现只需要保证即可,道理是一样的
时间复杂度,常数很小
一道dp好题!
只不过一开始的区间dp我就没想到,一开始觉得转移之间会有问题,就没去想了,自己yy了一个假做法
后面的一些优化都比较套路,只是我不会巧妙
T3
[字符串] [后缀自动机] [广义后缀自动机]
建广义SAM
,处理出表示节点,只有串的传统节点有的贡献的子树大小 节点的;是到根的之和
在SAM
上匹配串,找到每个前缀的对应节点,答案加上该结点的
即对的每个前缀,把答案加上所有后缀在中的出现次数
每个点到根的之和,就是其所有后缀的出现次数
9-6
Process
T1的小结论我讲课讲过,积分部分也不难;T3是已经没有什么好害怕的了的弱化版。。。
T2题没看懂,写了个乱搞拿了20分
考场上T3搞了很久才想起来做法,反映出自己容斥还是比较弱,需要加强
T1
[积分] [概率和期望] [方差]
首先有
后面显然就是,前面可以积分,原函数是,那么
最后化简一下,
T2
插头dp
T3
[容斥] [动态规划] [斯特林数]
容斥,设为恰好违反次规则的方案数,为至少违反次规则的方案数
然后考虑如何求
显然题目中的没有意义,把排序后就是一个的排列。于是转化为,求有多少个排列,至少有个位置满足
设表示考虑到第位,有个位置满足限制(不考虑顺序)的方案数,那么
今天才搞懂容斥是怎么回事。。。
这里表示的,有个限制的方案,指的是只保证这个限制一定满足,而其他的数完全不考虑如何填的方案数,它并没有什么实际意义。乘上之后才表示至少有个限制的方案数
而这里定义的,至少有个限制的方案数,也并不是真正意义上的至少。因为这里的
至少
是会算重的,否则为什么不等于正确的定义应该是,强制(钦定)个条件满足的方案数,只有这样才能从根本上使计数更加方便
这个转移很简单,若第个数满足限制,那么它能填前个数的某一个;又因为前面已经选了个数,所以它只有种选法
注意到,把数组第二维翻转后就是第二类斯特林数的形式
多项式可以优化到
9-8
Process
T1几分钟写完,T2看错题,以为所有关键点都要在联通块中,浪费了很久时间
T3最后二十分钟rush出来了
T1
或的答案就是整个数组,与的答案就是每个长度为的区间
T2
[动态规划]
用总联通块数
减去 不满足条件的联通块数
即可
对于每个点,统计以它作为联通块的最低点的方案
T3
[堆][贪心]
贪心枚举最右边到了哪一列,中间每一列至少选一个,最多选个,总共要选个
用一个小根堆随便维护一下
9-9
Process
T1搞了好久,矩阵快速幂推式子又推了半天!!!
然后剩下时间都在搞T2,写了一个退火乱搞只拿到了35分。考完之后发现T3是sb题
简单题还是做得太慢!!!
T1
[矩阵快速幂]
随便找规律/搞系数,矩阵快速幂优化
T2
[边双] [缩点] [背包] [动态规划] [计数]
显然先缩边双。一个直观的贪心是枚举每个点为根,然后每个点从父亲往它连边
但是这个做法很容易被hack掉
注意,题解中是表示这个边双的大小。。。
第一部分就是那个看成树的贪心,第二部分直接背包
T3
[set] [数据结构]
因为,于是考虑和值域相关的做法
对于每个权值维护一个set
,存该权值的出现位置
每次枚举一个权值,求出其位于当前区间内的出现次数,然后删掉这一段
计算出平均值后,按照题意重新赋值
直接暴力搞肯定不行,发现每次赋值都是一些连续段,于是set
维护pair
,存这样的连续段即可
时间复杂度不太会分析,但是看上去很对,跑得也很快
9-10
Process
现在开始联考了,考场状态还是有点问题,要多锻炼
先写的T2,写了个的做法,随便找找规律就找出来了。T1暴力状压,复杂度,可以随便跑。T3考场上想了个的背包,结果没调出来,应该是有问题的,因为不好组合
最后T3暴力还挂了分,很不应该
T1
[动态规划]
暴力状压
T2
找规律
T3
[概率和期望] [动态规划] [换根dp] [前缀和]
把题目中的贡献拆开,把拆到每个上
先枚举根,然后设表示只考虑子树时的期望答案,因为的每个子树是独立的,所以可以直接把期望乘起来,再考虑这个点的影响。若在值域序列中,插到最前面的位置(的概率),则贡献;否则(的概率)贡献
然后换根即可
因为可能等于0,所以要记个前后缀积来dp
另外一种做法:考虑每个点的贡献,设表示在为根情况下的,则它的要么是,要么是,要么是
在上差分一下即可
9-12
Process
玩了好久的T1。T2考过。T3暴力没写完
Summary
不知道为什么还是感觉时间不够,又出现了暴力写不完的情况
感觉这几天有点集中不了精力去想题。。。
T1
先从大到小贪心,然后前十二位爆搜一下所有方案
T2
[对偶图]
平面图转对偶图,把原图中的面看成点
T3
...
9-14
Process
三个比较规整的分,T2挂了20~30分,T3挂了20分
T1想得有点久,花了快半个小时的时间才想出来。T2搞了很久,因为没见过这个套路所以没搞出来。T3想了个假做法,写到一半才发现有问题
T1
[贪心]
从高位往低位贪心,每次看所有符合条件的边是否能使和连通
T2
[two pointers]
又是经典套路我不会系列
用两个栈维护队列,从而维护two pointers
。这个东西常用于没有可减性的问题上
具体实现见此
T3
[kruskal重构树] [分块]
建kruskal重构树,对询问分块
9-18
Process
今天可能是这段时间以来唯一一次自己稍微满意一点的模拟赛了吧。。。
T1花了二十分钟,T2先写的,然后优化到,然后优化到了的。T3写了个暴力
没挂分,考试过程中比较虚,花了比较长时间检查,以至于T3没有太多时间思考
T1
[前缀和]
把坐标系旋转45度,然后直接前缀和
T2
[计数]
考虑枚举逆序对的位置,统计它对答案的贡献
暴力计算的时候需要枚举第一个没卡到上界的位置,分五种情况讨论
很容易用前缀和优化到
再做一次前缀和,加上一点点非常简单的计数技巧就能优化到了
T3
[数据结构] [树状数组] [线段树] [set] [势能分析]
主要思想就是把询问离线,动态维护每个元素最右端位置,以统计答案
然后考虑链:给定的路径都是一段区间。也就是说,上述问题的每个元素变成了一段区间。
仍考虑上述做法,但需要支持快速把某一段区间的信息都更新
因为每次是整段整段地更新,每段内信息相同,于是考虑维护颜色段
直观的做法就是维护一个set
,每次找到与当前相交的所有颜色段(包括包含),将它们暴力一个个删掉,再把当前段加入
复杂度简单势能分析即可
具体实现时,可以用线段树代替set
,写起来更方便,没有细节。修改时要递归到只有一种颜色的区间(线段树维护min、max
,判断min == max
)
9-20
Process
先写的T2、T3,最后开的T1,T1写了很久,代码能力有点差。。。
T1
[树链剖分] [暴力]
注意到add
数量很少,于是每次重构树剖即可
如果线段树维护的话,重构复杂度是(线段树build
是),询问
ST表
维护的话,重构复杂度,询问
T2
[线性筛] [欧拉函数]
线性筛即可
T3
[后缀自动机]
SAM
随便算一下本质不同子串
9-21
Process
这场考得中规中矩,T3
还有一些部分分可以拿到的,还是因为搞T2
时间太长了,没时间写了
前两题没有挂分,希望以后也要保持
T1
[概率和期望]
根据期望的线性性,转化成求每个点期望之和。每个点期望就是,表示在它前面要经过多少个点才能到-1
,树上算下深度即可
T2
[动态规划] [贪心]
设表示从开始,需要多少体力才能不停顿地走完的子树(也就是把所有体力放到一开始加满)
设表示子树中所有点权减两倍边权
树形dp,考虑从的儿子转移到
此时,就要先加上,要先减去(考虑当前这条边,以下的和均已进行完此操作)
不难发现,如果加满体力走完整棵子树的话,体力值会变化
那么的儿子肯定要先遍历,且按照从小到大遍历
的儿子后遍历,且按照从大到小遍历
按照这个顺序依次访问儿子即可
T3
前70分都比较可做,组合计数随便算算。满分做法需要复杂的分类讨论
9-23
Process
今天T1卡了好久的常,T2T3都没什么时间了
T2比较神仙,思路不是很容易想
T1
[模拟]
发现答案就是进制下的数位和模的值
暴力模拟进位即可
T2
[矩阵快速幂] [状态压缩]
把排列看成置换。因为每个数地位相等,可以转化成某个排列要变成单位置换()
为什么要这么转化下面会讲
考虑在暴力的基础上优化,要把状态数量从压下来:只记录本质不同的置换(只记录每种长度的轮换个数)
举个例子:,它有三个轮换分别是。于是记录表示有大小为的轮换各一个
相当于是原来的一些本质相同的状态,被缩成了一个大状态
总状态数是整数分拆的方案数,只有左右
这样记录的话,处于同一个大状态中的每个小状态,它们的所有后继状态所处的大状态集合是相同的(好像有点绕)
并且,这样记录能够使终结点唯一地表示出来(个长度为的环是唯一的,这就是为什么一开始要转化)
于是就可以直接矩阵快速幂计算答案了
具体实现上稍微有点复杂
T3
[拓扑排序] [拆点]
sol from gc
9-24
Process
T3以前见jwb做过,但是自己写的时候还是花了很长时间,最后只剩半个多小时写T1和T2了。
一开始花了很长时间看T1题意,但是又没写,浪费了较长时间,时间分配不合理,以后要注意
T1
[模拟]
化学题大模拟
T2
[动态规划] [贪心]
若给定的区间两两互不包含时是很好做的,因为排序后每次选的肯定是连续的一段
表示到第个区间,分了组的答案,枚举下一段是从到,有转移
是区间的左右端点
再考虑存在包含的情况
若含于中,则 要么和放一组中,要么单独放一组
若和其他区间放一组,那把放到所在的组中,组答案不变,原来的组答案不会更劣
于是把只要包含了别的区间的区间单独提出来,贪心取较长的;剩下的区间做上述dp即可
最后再枚举两部分取的数目,把两部分合并起来即可
T3
[启发式分治]
先分解质因数,对每个位置求出,左边和右边第一个不与它互质的数的位置
这一步实现的时候要预处理每个数的最小质因子,否则时间很大
首先发现一个性质:若序列中的某个子区间不合法,则整个序列一定不合法
这个子区间无法被分隔开,最后一定会递归到这个区间上
于是可以每次利用,找出任意一个满足和其他数都互质的数作为根(判断),再递归两边处理,伪代码如下:
但是这是的
考虑启发式分治,即从两边同时向中间扩展:
这样复杂度就是的了,因为,是启发式合并的逆过程
注意:从中间往两边搜是错的。因为只有从两边向中间搜才能保证搜到的点不在同一个区间中(左半边,右半边)
9-26
Process
两道原题,一道昨天才考过的题,不评价
T1
直接dp
T2
启发式分治即可
T3
[计算几何] [曼哈顿与切比雪夫距离]
首先找到所有交点:把线段按左边从小到大加入,统计它被哪些线段穿过即可
第二问直接曼哈顿转切比雪夫即可
对于第一问,设交点个数为,则
“对向交换”最多发生次,最少发生次。其中为“右边相对于左边的位置的排列的轮换数量”
比如,右边从下往上依次是.那么轮换就是.共两个
9-27
Process
状态不是很对,8:30之前一直没动键盘。T1想好久没想出来,T2也一直没想清楚
感觉今天静不下心来想题,要赶快调整状态了
T1
[生成函数] [卷积] [FWT]
设生成函数
那么在子集并卷积意义下,若,那么就能对产生贡献
这样暴力每次把两个卷起来是的,但是因为也很小,所以先把每个DWT
一下,把相同的放一起加,最后在把每个IDWT
回去。大概是这个意思:
1 | for (int i = 0; i < M; ++i) DWT (F[i], 1 << N, 0); |
复杂度
T2
[启发式合并] [贪心] [set]
显然可以从叶子往上贪心。一开始把所有路径都加上,碰到不合法的点就把包含它且顶端深度最浅的路径删掉
包含它这个条件即为路径底端的点
在它的子树内;可以在树上合并
深度最浅的条件可以用multiset
维护
所以multiset
启发式合并,动态维护可选路径集合即可
T3
...
9-30
Process
一道高考题,一道模拟题,一道原题
模拟题挂分挂得好惨。。。
T1
[赌徒破产问题] [特征方程] [数学]
2019年高考理科数学最后一题,只不过把数字换成了字母
随便推下式子特征方程搞下就可以了
T2
[模拟]
简单模拟题。用queue
和list
模拟即可。list
是维护当前场上还剩下的人,以优化常数