Now you have a string consists of uppercase letters, two integers AA and BB. We call a substring wonderful substring when the times it appears in that string is between AA and BB (A \le times \le BA≤times≤B). Can you calculate the number of wonderful substrings in that string?
Input
Input has multiple test cases.
For each line, there is a string SS, two integers AA and BB.
\sum length(S) \le 2 \times 10^6∑length(S)≤2×106,
1 \le A \le B \le length(S)1≤A≤B≤length(S)
Output
For each test case, print the number of the wonderful substrings in a line.
样例输入复制
AAA 2 3 ABAB 2 2
样例输出复制
2 3
题目来源
题解:SAM模板题
参考代码:
//H 求子串出现次数在k1=<num<=k2; #include <bits/stdc++.h> using namespace std; const int MAXN = 4e5+10; char ss[200005]; const int LetterSize = 26; int tot, last,ch[MAXN][LetterSize],fa[MAXN],len[MAXN]; int sum[MAXN],tp[MAXN],cnt[MAXN]; void init() { last = tot = 1; len[1] = 0; memset(ch,0,sizeof ch); memset(fa,0,sizeof fa); memset(cnt,0,sizeof cnt); } void add( int x) { int p = last, np = last = ++tot; len[np] = len[p] + 1, cnt[last] = 1; while( p && !ch[p][x]) ch[p][x] = np, p = fa[p]; if(p == 0) fa[np] = 1; else { int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else { int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } void toposort() { for(int i = 1; i <= len[last]; i++) sum[i] = 0; for(int i = 1; i <= tot; i++) sum[len[i]]++; for(int i = 1; i <= len[last]; i++) sum[i] += sum[i-1]; for(int i = 1; i <= tot; i++) tp[sum[len[i]]--] = i; } int main() { int k1,k2; while(scanf("%s",ss)!=EOF) { init(); scanf("%d%d",&k1,&k2); long long ans=0; for(int i=0,len=strlen(ss);i<len;i++) add(ss[i]-‘A‘); toposort(); for(int i=tot;i;i--) { int p=tp[i],fp=fa[p]; cnt[fp]+=cnt[p]; if(cnt[p]>=k1 && cnt[p]<=k2) ans+=len[p]-len[fp]; } printf("%lld\n",ans); } return 0; }
原文地址:https://www.cnblogs.com/songorz/p/9651909.html
时间: 2024-11-05 14:42:00