GDOI2017总结

GDOI2017总结

By Semiwaker


总述:

分数

Day1 235
Day2 175
Day3 70

状态

Day1状态较好;Day2第一题居然出现了错误,有点头脑混乱;Day3完全不知在干什么。


题目

Day1

T1

题目大意

给出多个个字符串,按顺序进行字符串替换操作。
每一次给出一个替换规则a->b,从左到右匹配字符串中的a换成b,新生产的字符不参与当次替换。

题解

直接KMP。

考试状态

一开始看错题目,以为所有替换同时进行,只是优先做前面的,写了个AC自动机然后发现不对劲。应该把样例都看完再做的。耽误了比较多的时间。

T2

题目大意

给出一棵树,每个点有一个点权。对于每一个点x,求除了子树x之外的部分的mex。

题解

考虑哪些子树会把所有的 0 都删除?
所有的权为 0 的点的 LCA 到根的路径上每一个点都会,其他都不会。
类似,全部 1、2、3……都是如此。
那么我们在 0 的 LCA 标记上一个 0 , 1 的 LCA 标记上 1……
然后考虑某个点x的mex值,显然是它子树内最小的标记。
DP即可。

考试状态

面对5000字题面我选择看最后一段。
虽然很纠结是图还是树,但我觉得反正图不会做,就当它是树好了。
从A了这题这一点来开,这种心态还是有可取之处的。

T3

题目大意

给出一堆Trie,每次询问一个集合的最长公共子串。

题解

在Trie上建广义后缀自动机。
由于出题人卡在线(也就是按照 DFS 序建),所以要用 BFS 序建 SAM。

考试状态

写后缀数组的TLE了。
我考前还想着不会考SAM来着。

T4

题目大意

问正n边形三角划分后,能数出多少k边形?

题解

先选出一个k边形,然后再三角划分。
方案数为选出k边形后,切出来每一个部分分别三角划分的方案的乘积。
显然三角划分的方案为卡特兰数。
实际上就是卡特兰数的生成函数的k次卷积的第n-k项,再乘个k变形的三角划分方案数。
k次卷积可以用FFT+快速幂搞定。

考试状态

根本没去想这题。


Day2

T1

给出一个H个n*m的,表示地图。
有障碍物和传送门,求最短路。
传送门可以到下一层的同类传送门处,且不花费时间。

题解

SPFA即可。当然,只有0和1也可以BFS。
注意可能有两层全部都是同一种传送门,这样边会很多。解决方法是建虚点,每一层对每一种传送门建一个虚点。

考试状态

我居然RE了。没找到原因,不过可能是重视程度不够。

T2

题目大意

每次插入一个64位01串,求已经插入的串中,和当前串汉明距离为3的有多少个?
(汉明距离:两个串不同的位的数量)

题解

把64位分成4组16位。
因为汉明距离为3,至少有一组16位是完全相同的。
这样我们可以开4个2^16的桶,每次枚举完全相同的那16位。
暴力枚举,然后计算汉明距离为3的有多少个。
注意重复的情况,暴力枚举的时候计算有几组16位是完全相同的,除一下就好了。
关键点是怎样分成4组16位。由于不知道出题人是怎么卡的,最好的方法就是让每一个桶都装尽量少的01串。(随机乱搞??

考试状态

写了个Trie,在Trie上爆搜。本来想像kd-tree那样写的,但是发现效率还不如Trie。没想过容斥。

T3

题目大意

给出两个串。设串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]匹配。如果位置没有变化就不用输出。
具体位置的变化用个树状数组维护下就好了。

考试状态

想了比较久才做出。打方案的细节比较麻烦。

T4

题目大意

给出一棵树,这棵树表示地图。
再给出一棵树,这棵树为关系树。
关系树上的每一个点表示一个人,这个人在地图上有一个固定的位置。
每个人有一个范围区间 [L,R] ,表示这个人的半径可能的取值区间。每个半径都有等概率取到。
每次在关系树上选两个点,求这两点路径上每一个人,点z期望在多少个人的半径内?
还要支持修改:在关系树上加叶子。
强制在线。

题解

留坑待填

考试状态

没想过这题。


Day3

T1

题目大意

给出一棵树,每个点有两个值 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里面。
实际状态应该没有理论上限那么多。

考试状态

写了个爆搜。完全没有考虑过按顺序填。

T2

题目大意

有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

考试状态

写了个三分套三分套三分……一看就不靠谱。
然后试着写分治+三分。然后算主定理发现时间复杂度纯粹搞笑。

T3

题目大意

定义合法串为:总和为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。

考试状态

根本没想过前缀和。完全不会做。

T4

题目大意

给出一棵树,有点权。
要求维护3个操作:
1、路径加。
2、路径求和。
3、路径轮换。即如果路径上的权值为a->b->c,则轮换后权值变为c->a->b。依此类推。

题解

方法一:树链剖分+Splay。
每一条链用一个Splay来维护,路径轮换按照定义做就好了。
比较难写。
方法二:LCT
维护一棵形态树和一棵数值树。
在链的切分上,两颗树是相同的。
对于同一条链,两棵树之间从头开始一一对应。
这样只需要维护树之间的对应关系,就可以找到点之间的对应关系。
在链(Splay)的根维护对应关系,然后知道是第几个就可以找到了点的对应关系了。
在进行所有操作时,都同时操作形态树和数值树就可以保证链一一对应。


By SemiWaker

你可能感兴趣的:(OI,GDOI,考试,GDOI,考试,总结)