题意:
给定整数M L
一个字符串s
我们定义一个子串为"好"串 iff
1、长度为 M*L
2、把这个好串分成M段,每段长度为L,且每段各不相同。
且我们得到的这些好串不重复计算(即把这些好串去重)
问有几个好串
#include <stdio.h> #include <cstring> #include <iostream> #include <map> using namespace std; typedef unsigned long long ull; const int N = 100005; int n, m; char s[N]; ull base[N], has[N], bas = 31; map<ull, int>mp; int main(){ base[0] = 1; for(int i = 1; i < N; i++)base[i] = base[i-1]*bas; while(cin>>n>>m){ scanf("%s", s); int slen = strlen(s); has[slen] = 0; for(int i = slen-1; i >= 0; i--) has[i] = has[i+1]*bas+s[i]-'a'+1; int ans = 0; for(int i = 0; i < m && i+n*m<=slen; i++) { mp.clear(); for(int j = i; j < i+n*m; j+=m) { mp[ has[j] - has[j+m]*base[m] ] ++; } ans += mp.size() == n; for(int j = i+n*m; j+m <= slen; j+=m){ ull tmp = has[j-n*m] - has[j-(n-1)*m]*base[m]; mp[tmp] --; if(mp[tmp]==0)mp.erase(tmp); tmp = has[j] - has[j+m]*base[m]; mp[tmp]++; ans += mp.size() == n; } } cout<<ans<<endl; } return 0; }
时间: 2024-10-12 13:05:39