参考了网上的代码;
这题主要用的就是Rabin-Karp的hash算法原理;
dp[i]表示i后面字符串的hash值,要算出S[i...i+m]的hash值的话就是:tmp = (dp[j] - dp[j+len]*nbase[len]);
这题问的就是原串有多少个满足条件的substring;
(i) It is of length M*L;
(ii) It can be constructed by concatenating M “diversified” substrings of S, where each of these substrings has length L; two strings are considered as “diversified” if they don’t have the same character for every position.
这里只需要枚举每个串的头就行了,substring中含有n个长为len的串,那么枚举了头i,然后求出后面连续n个长为len 的串的hash值放到mp中,满足条件的充要条件就是mp的大小为n,然后把前面的第一个长为len的hash值-1,如果为0 的话就移除mp中,然后后面又加入一个长为len 的串的hash值,具体操作看代码。
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name :Rabin-karp hash Algorithm. *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back #define lson rt << 1 #define rson rt << 1 | 1 typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1e5 + 10; char s[maxn]; int n, len, slen; ULL nbase[maxn]; ULL dp[maxn]; const ULL base = 31; map<ULL,int> mp; int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); nbase[0] = 1ULL; int i, j; for (i = 1;i < maxn;++i) nbase[i] = nbase[i-1]*base; while(~scanf("%d%d",&n,&len)) { scanf("%s", s); // puts(s); slen = strlen(s); dp[slen] = 0; for (i = slen - 1;i >= 0;--i) { dp[i] = dp[i+1]*base + (s[i] - '0'); // printf("******* %lld\n", dp[i]); } int answer = 0; for (i = 0;i < len && i + n*len <= slen;++i) { mp.clear(); for (j = i;j < i + n * len;j += len) { ULL tmp = (dp[j] - dp[j+len]*nbase[len]); mp[tmp]++; // printf("%lld\n",tmp); } if (mp.size() == n) answer++; for (j = i+n*len;j + len <= slen;j += len) { ULL tmp = dp[j-n*len] - dp[j-(n-1)*len]*nbase[len]; mp[tmp]--; if (mp[tmp] == 0) mp.erase(tmp); tmp = dp[j] - dp[j+len]*nbase[len]; mp[tmp]++; if (mp.size() == n) answer++; } } printf("%d\n", answer); } return 0; }