Day1 235
Day2 175
Day3 70
Day1状态较好;Day2第一题居然出现了错误,有点头脑混乱;Day3完全不知在干什么。
给出多个个字符串,按顺序进行字符串替换操作。
每一次给出一个替换规则a->b,从左到右匹配字符串中的a换成b,新生产的字符不参与当次替换。
直接KMP。
一开始看错题目,以为所有替换同时进行,只是优先做前面的,写了个AC自动机然后发现不对劲。应该把样例都看完再做的。耽误了比较多的时间。
给出一棵树,每个点有一个点权。对于每一个点x,求除了子树x之外的部分的mex。
考虑哪些子树会把所有的 0 都删除?
所有的权为 0 的点的 LCA 到根的路径上每一个点都会,其他都不会。
类似,全部 1、2、3……都是如此。
那么我们在 0 的 LCA 标记上一个 0 , 1 的 LCA 标记上 1……
然后考虑某个点x的mex值,显然是它子树内最小的标记。
DP即可。
面对5000字题面我选择看最后一段。
虽然很纠结是图还是树,但我觉得反正图不会做,就当它是树好了。
从A了这题这一点来开,这种心态还是有可取之处的。
给出一堆Trie,每次询问一个集合的最长公共子串。
在Trie上建广义后缀自动机。
由于出题人卡在线(也就是按照 DFS 序建),所以要用 BFS 序建 SAM。
写后缀数组的TLE了。
我考前还想着不会考SAM来着。
问正n边形三角划分后,能数出多少k边形?
先选出一个k边形,然后再三角划分。
方案数为选出k边形后,切出来每一个部分分别三角划分的方案的乘积。
显然三角划分的方案为卡特兰数。
实际上就是卡特兰数的生成函数的k次卷积的第n-k项,再乘个k变形的三角划分方案数。
k次卷积可以用FFT+快速幂搞定。
根本没去想这题。
给出一个H个n*m的,表示地图。
有障碍物和传送门,求最短路。
传送门可以到下一层的同类传送门处,且不花费时间。
SPFA即可。当然,只有0和1也可以BFS。
注意可能有两层全部都是同一种传送门,这样边会很多。解决方法是建虚点,每一层对每一种传送门建一个虚点。
我居然RE了。没找到原因,不过可能是重视程度不够。
每次插入一个64位01串,求已经插入的串中,和当前串汉明距离为3的有多少个?
(汉明距离:两个串不同的位的数量)
把64位分成4组16位。
因为汉明距离为3,至少有一组16位是完全相同的。
这样我们可以开4个2^16的桶,每次枚举完全相同的那16位。
暴力枚举,然后计算汉明距离为3的有多少个。
注意重复的情况,暴力枚举的时候计算有几组16位是完全相同的,除一下就好了。
关键点是怎样分成4组16位。由于不知道出题人是怎么卡的,最好的方法就是让每一个桶都装尽量少的01串。(随机乱搞??)
写了个Trie,在Trie上爆搜。本来想像kd-tree那样写的,但是发现效率还不如Trie。没想过容斥。
给出两个串。设串A为目标串,串B为起始串,保证两个串每种字符数量相同。
每次在串B中选一个字符,将它移动到前面的某个位置。
求最少步数使得B和A相同,打方案。
设 f[x][y] 为使得A的前x个字符与B的前y个字符匹配的最少移动次数。
(实际上,当x>y的时候,B的后面的字符要移动到前面来匹配A,注意到B后面的字符数量是固定的,所以空出来的字符数量也是固定的,只要保证A[x]有匹配的字符即可。)
转移类似LCS。
如果A[x]=B[y],那么可以不用移动,转移到f[x-1][y-1]。
否则,有两种转移:
将B[y]移动走,再让A[x]和B[y-1]匹配,转移到f[x-1][y-1]+1。
让B[y+1..n]中的多出来的字符和A[x]匹配,前提是B[y+1..n]中有空余的。可以预处理得到。然后转移到f[x-1][y]。注意不用+1,因为之前取出该字符的时候,已经计算了。
现在是关键问题,打方案。
首先,在转移的时候要记录从什么转移而来。
注意到x肯定是从x-1转移而来,所以只用记录y的位置即可。
x从后往前,每次将上一次的y到这一次的所有y都取出来。
然后放下一个B[y]和A[x]匹配。如果位置没有变化就不用输出。
具体位置的变化用个树状数组维护下就好了。
想了比较久才做出。打方案的细节比较麻烦。
给出一棵树,这棵树表示地图。
再给出一棵树,这棵树为关系树。
关系树上的每一个点表示一个人,这个人在地图上有一个固定的位置。
每个人有一个范围区间 [L,R] ,表示这个人的半径可能的取值区间。每个半径都有等概率取到。
每次在关系树上选两个点,求这两点路径上每一个人,点z期望在多少个人的半径内?
还要支持修改:在关系树上加叶子。
强制在线。
留坑待填
没想过这题。
给出一棵树,每个点有两个值 a 和 b,其中 a 固定,b 未给出。
如果点 x 是点 y 的祖先,且 bx>by,则发生 ax 次战争。
所有 b 都在 [0,m] 内,求填写 b 的方案数,使得刚好发生 k 次战争。
n 14 m 1e8 k 20
实际上,只需要关心b之间的相对大小即可,最后乘以 Cpm ,其中p表示b有p种取值。(显然p<=n)
我们先枚举个p,然后从小到大把b填好。
设f[p][S][k]表示放了p次,已经放了的集合为S,战争次数为k。
每次枚举一个没有放的子集,然后考虑每一个点的祖先中有多少个点还没有放,也就是有多少个点比当前点大,计算总贡献加到k里面。
实际状态应该没有理论上限那么多。
写了个爆搜。完全没有考虑过按顺序填。
有n个技能,每秒钟消耗mi的魔力和hi的生命,造成di的伤害。
已知总魔力为MP,总生命为HP,求每个技能的释放时间,使得总伤害最大。
除n外所有数为实数。
把(mi,hi)当成一个向量,那么n个向量的线性组合应该指向上边界、右边界或者(MP,HP)。
发现一个问题,如果答案是是3个向量a、b、c的线性组合,且3个向量都不共线(显然共线没有意义)。那么说明c优于a和b的线性组合,那么只有c会更优。
所以答案要么只放一个技能,要么只放两个技能。O(n^2)的暴力枚举即可。
(貌似直接单纯形能A)
写了个三分套三分套三分……一看就不靠谱。
然后试着写分治+三分。然后算主定理发现时间复杂度纯粹搞笑。
定义合法串为:总和为10的倍数的串。
定义幸运串为:每一个数都在某个合法子串中的由0-9组成的串。
求长度为n的幸运串数量。
首先,用前缀和(mod 10)来表示串,这样比较好描述子串。
合法串显然为开头和结尾的前缀和相同的串。
幸运串是被最长的合法串覆盖的串。
那么我们这么考虑:
如果我们每次加入最后一个前缀和(显然任意前缀和都可以构造出来),那么怎样构成幸运串?
哪些位置是没有被覆盖的?显然是后面的那些。
那么我们设从开头最多覆盖到某个位置k,从0到k出现的前缀和集合为S1。
从k到结尾出现的前缀和集合为S2。
那么就有3中选择了。
选择放S1中的数,那么就完整覆盖了整个串,S2清空。
放S2中的数,无论放那个都没有完整覆盖整个串,不变。
放没有出现过的数,显然不会改变覆盖情况,加入S2里面。
特殊情况:S1为空,那么放S2的第一个数会导致完整覆盖,放其他不变。
注意我们不需要知道S1和S2具体是什么,只要记下大小即可。
然后写个矩阵乘法。
答案是S2为空的所有状态的和。
初始状态S1位为空,S2中有一个0。
根本没想过前缀和。完全不会做。
给出一棵树,有点权。
要求维护3个操作:
1、路径加。
2、路径求和。
3、路径轮换。即如果路径上的权值为a->b->c,则轮换后权值变为c->a->b。依此类推。
方法一:树链剖分+Splay。
每一条链用一个Splay来维护,路径轮换按照定义做就好了。
比较难写。
方法二:LCT
维护一棵形态树和一棵数值树。
在链的切分上,两颗树是相同的。
对于同一条链,两棵树之间从头开始一一对应。
这样只需要维护树之间的对应关系,就可以找到点之间的对应关系。
在链(Splay)的根维护对应关系,然后知道是第几个就可以找到了点的对应关系了。
在进行所有操作时,都同时操作形态树和数值树就可以保证链一一对应。