https://www.luogu.org/problemnew/show/P2031
开始,我认为需要枚举所有的子串来判断是否包括列表中的某个字符串。因为给定字符串包括L个字符,就会有L²个子串,依次枚举列表中所有的字符串,就会有n种可能,再执行KMP。在每个子串单拿出来做KMP时,每个子串的均摊最好平均复杂度是L/3,因为从0-1中随机选两个数,它们的平均距离是1/3。而最坏平均复杂度是2L/3,就是当列表里的每个字符串都恰好对应每个子串,要是再长,就比子串长了,可以直接break。综合下来,最好复杂度是nL³/3属于O(nL³),最坏复杂度是2nL³/3也属于O(nL³),所以就是O(nL³)n最大是500,L最大是300。所以就到了37,500,000,000。如果每秒进行一千万次循环,就需要3750秒,明显超时。
后来想到,可以对于每个起点,用二分来寻找第一次包含列表里的某些字符串的终点。复杂度O(L²logL)。因为L是300,所以最大为2,430,000。不会超时。
所以,要用预处理来避免很多的循环摞起来导致超时。循环分着做要比合着做快。
预处理优化时间复杂度
最新推荐文章于 2025-07-14 10:25:41 发布