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
题目来源
题意:计算出现次数为A到B的子串个数。
思路:构造后缀自动机,拓扑排序算出每个集合的出现次数,然后用当前MAX减一下父亲集合的MAX就能算出每个集合的子串数量了。
# include <iostream>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 2e5+30;
char s[maxn];
int g[maxn][26], pre[maxn], mx[maxn];
int b[maxn], f[maxn], id[maxn];
int sz, last;
void newnode(int s){
mx[++sz] = s;
pre[sz] = 0;
memset(g[sz], 0, sizeof(g[sz]));
}
void init(){
sz = 0;
last = 1;
newnode(0);
}
int ins(int x){
newnode(mx[last] + 1);
int p = last, np = sz;
while(p && !g[p][x]){
g[p][x] = np;
p = pre[p];
}
if(p){//边发生冲突
int q = g[p][x];
if(mx[q] == mx[p] + 1) pre[np] = q;//新增结束点,不改变原图
else{
newnode(mx[p] + 1);//新增点
int nq = sz;
for(int j=0; j<26; ++j) g[nq][j] = g[q][j];
pre[nq] = pre[q];
pre[q] = pre[np] = nq;
while(p && g[p][x] == q){
g[p][x] = nq;
p = pre[p];
}
}
}
else
pre[np] = 1;
last = np;
}
int main(){
int L, R;
while(~scanf("%s%d%d",s+1,&L,&R)){
init();
memset(b, 0, sizeof(b));
memset(f, 0, sizeof(f));
memset(id, 0, sizeof(id));
int len = strlen(s+1);
for(int i=1; i<=len; ++i) ins(s[i]-'A');
for(int i=1,p=1; i<=len; ++i)
p = g[p][s[i]-'A'],++f[p];//主链加上1,表示至少出现1次
for(int i=1; i<=sz; ++i) ++b[mx[i]];//基数排序
for(int i=1; i<=len; ++i) b[i] += b[i-1];
for(int i=1; i<=sz; ++i) id[b[mx[i]]--]=i;//排在第i的是哪个集合
for(int i=sz; i; --i) f[pre[id[i]]] += f[id[i]];//按拓扑序累加
LL ans = 0;
for(int i=2; i<=sz; ++i)
if(f[id[i]] >= L && f[id[i]] <= R)
ans += mx[id[i]]-mx[pre[id[i]]];
printf("%lld\n",ans);
}
return 0;
}