本题的hash解法
作者由于只有CSPJ水平,所以根本想不出KMP或者什么自动机解法。只会hash+二分
虽然该算法复杂度为O(Tnlogn),但是常数小,可以通过。。
考虑j>i,如果i~j这个字符串同时是串1-j的前缀和后缀,那么我们可以认为位置i对num[j]做出了1的贡献。
然后我们枚举i,看它可以对哪些num[j]产生贡献。容易发现如果k<j且i对num[j]产生了贡献,那么i也一定会对num[k]产生贡献。因此我们可以二分出一个x,使得i对num[i]->num[k]产生贡献,且不会对num[k+1]->num[n]产生贡献。
然后考虑二分过程中如何checki是否对当前的mid(我设的mid是j-i+1的值即前/后缀的长度)产生贡献:用hash判断一下字符1->mid组成的字符串和字符x->x+mid-1组成的字符串是否相同就可以了。然后统计答案就用差分数组乱搞一下就好了。
枚举i是o(n)的,二分是o(logn)的,所以总复杂度为o(Tnlogn),因为常数小可以通过。
上文中的->可以理解为~,因为作者对markdown太不了解所以只能这么写了。
排版很丑,表述很垃圾,代码也丑,希望轻喷。
code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,mod=1e9+7,md=19260817;char c[N];int hash[N],n,pre[N],pows[N];
inline void work(int x)