这个拖了很久。。。
先是round24
第一题是kmp+dp。。。。这里其实关键的地方是要知道kmp匹配自己时。。如果整个前缀的长度 是错位部分(即f[i]~i)长度的整数倍。。。那么错位部分就刚好是这个前缀最短的一个周期。。。
第二题就是平衡树,代码敲熟就好
第三题:给出一个图,多次询问连接两点的路径上必须经过的边有几条。。。其实就是求两点之间桥的个数。。。tarjan求出所有桥,然后把每个边双连通分量缩点得到一颗树,再用lca倍增算法求中间的路径长度。。这题还是挺裸的。。。但是当时看到完全没感觉啊,还是太弱了
round 26
第一题:把几种直接可以出答案和永远出不了答案的情况特判一下。。。其他的情况的算法其实就是求gcd。。。辗转相除即可(当时完全没看出来啊)
第二题:这道题出题人给的题解居然是打表+搜索,233333。不过贴吧上有人给了一些比较好的方法。。。第一个就是按照非严格递增的顺序枚举,最后做一次01背包判断方案是否可行。。。然后答案数+=当前方案的可重排列数。。。可重排列需要除掉的那一部分可以在枚举过程中维护出来。
还有个牛逼的改进就是:01背包的dp状态用long long的二进制来表示...每次转移就只需要O(1)了。。。这个也可以在枚举过程中维护出来。
第三题:其实就是一个bfs而已。。只不过状态的扩展有点麻烦。。这个静下心去写应该还是能写对的
第四题:区间修改,求区间gcd。。。先想下点修改的:可以用线段树做。 因为gcd(al,al+1,al+2,……,ar)=gcd(gcd(al,al+1,...,ak),gcd(ak+1,...,ar));直接维护就好了。。我当时想了半天都没想到T_T。 然后区间修改可以这么来弄:用线段树维护原序列的差分序列,然后区间修改就变成了修改两个点。。
因为有 gcd(al,al+1,...,ar)=gcd(al, al+1 - al, al+2 - al+1,...,ar - ar-1)...所以查询l到r的gcd时。。。就是求gcd(al,gcd(al+1-al,...,ar - ar-1))了。。。前面那个al实际上就是差分序列的第一项到 al - al-1这一项的和
第五题:太高端还没弄懂