Codeforces Round 856 (Div. 2)
1|0Preface
补题,话说这场题目数量好少的说……
除了E题有点新花样前面题目都很简单的说,不过最后一天疯狂卡自然溢出的Hash,WA了一页可还行
2|0A. Prefix and Suffix Array
SB题,我们把前缀对应的长度为的串找出来之后,把剩下一个字母接在后面直接判断即可
3|0B. Not Dividing
不难发现,若,则,因此直接贪心地判断每个数要不要加即可
但注意一个坑点,必须先把所有的都变成再操作,不会会卡死一直TLE的说
4|0C. Scoring Subsequences
首先利用单调不降的性质,我们知道对于的答案,其右端点一定为,只要考虑左端点最多延申到哪里即可
把贡献关于下标的式子写出来,不难发现左端点的取法是单调的,因此用two pointers
扫一下即可
5|0D. Counting Factorizations
简单数数题,但应该有多项式优化的方法把复杂度变成的,懒得想了
首先我们统计出个数中不相同的质数个数,若则直接无解
否则我们考虑从这个数中选出个数,不难发现每一种方案之间的答案肯定是互异的,因为只要一个质数不同两个数肯定不同
那么只要考虑底数相同时的方案数即可,不难发现这就是个可重全排列,计算起来十分方便
我们先考虑排除这个质数后剩下的可重全排列的方案数为,再考虑这个质数中,设出现的总次数为,若不选择它为底数,则对应的要乘上
因此我们可以很容易地想到一个DP,设表示前个不同的质数中选择个为底数时的总贡献,转移就非常trivial了
总复杂度
6|0E. Labeling the Tree with Distances
利用基于深度的多项式Hash来快速统计,算是个很有启发性的trick了
虽然被卡自然溢出很气,但又学到了一种新的写Hash的综合性技巧,还是收获满满
我们考虑对于每一个点维护一个Hash值,,其中为当该点为根节点时深度为的点的个数,是Hash种子
这样写不仅可以很方便地统计关于这道题的答案信息,而且在假定号点为根求出所有点子树内的Hash值之后可以用换根操作找出所有点的Hash值
最后考虑有一个点的标记是任意的,不难发现最终的不同的可能取值只有种,我们暴力枚举最后一个标记的取值,然后用set
维护
最后对于每个点,直接查询set
中是否有与之Hash值相等的值即可,总复杂度
然后讲一下Hash部分,前面我用的自然溢出的双Hash一直被卡爆,然后改普通Hash(但模数取值范围还是int
内的),改三Hash什么的都不行
于是只能去膜拜一手dalao的写法,遂令人大开眼界
首先是随机数种子的选取,我之前的方法就是大概这样
但这种方法找出来的随机数并不均匀,很容易被卡
因此我们可以利用C++标准库中的random
库里自带的std::mt19937_64
来帮助生成随机数,在使用梅森算法的基础上,用这种方式生成随机数会更优秀,具体关于std::mt19937_64
的姿势可以看这里
另外一个问题就是如果我们把模数选的很大,虽然撞车的概率大大降低,但是做乘法的时候就会溢出,但是用龟速乘又太慢
那么又涉及到一个好东西,直接开个unsigned __int128
,记录乘积然后再取模即可(貌似之前见到的快速乘都是用long double
的,但那东西说实话不太可靠的说)
利用上面两个科技我们就能通过这道200+个测试点的花式卡Hash的题了(注意开C++11及以上版本)
7|0Postscript
现在一周的时间安排就很不均匀,周一到周三课特别满一点时间刷题都没有
但是周四到周日就挺多空闲时间的说,要狠狠地补题
__EOF__

本文链接:https://www.cnblogs.com/cjjsb/p/17197190.html
关于博主:复活的ACM新生,目前爱好仅剩Gal/HBR/雀魂/单机/OSU
版权声明:转载请注明出处
声援博主:欢迎加QQ:2649020702来DD我
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2018-03-09 Luogu P1993 小 K 的农场