输入一个字符串,求出现K次得子串个数
我的做法是求出大于等于K次的子串个数-大于等于K+1次的子串个数
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10;
const int maxx = 127000;
struct Node {
int pre, nxt[26];
int step, number1, num;
void Clear() {
step = number1 = num = 0;
pre = -1;
memset(nxt, -1, sizeof(nxt));
}
} st[maxn<<1];
int t, root, last, cur, k;
LL ans, tmp;
char str[maxn];
void init() {
cur = 0;
root = last = cur++;
st[root].Clear();
}
void extend(int w) {
int np = cur++, p = last;
last = np;
st[np].Clear();
st[np].step = st[p].step+1;
while(p != -1 && st[p].nxt[w] == -1)
st[p].nxt[w] = np, p = st[p].pre;
if(p == -1)
st[np].pre = root;
else {
int q = st[p].nxt[w];
if(st[q].step == st[p].step+1)
st[np].pre = q;
else {
int nq = cur++;
st[nq].Clear();
st[nq].number1 = st[q].number1;
st[nq].num = st[q].num;
memcpy(st[nq].nxt, st[q].nxt, sizeof(st[q].nxt));
st[nq].pre = st[q].pre;
st[nq].step = st[p].step+1;
st[np].pre = st[q].pre = nq;
while(p != -1 && st[p].nxt[w] == q)
st[p].nxt[w] = nq, p = st[p].pre;
}
}
int f1 = 0, f2 = 0, pp = np;
while(np!=-1 && (!f1 || !f2)){
if(f1 == 0 && st[np].number1 < k) {
st[np].number1++;
if(st[np].number1 == k){
ans+=(LL)st[np].step-st[st[np].pre].step;
f1 = 1;
}
}
if(f2 == 0 && st[np].num < k+1) {
st[np].num++;
if(st[np].num == k+1){
tmp+=(LL)st[np].step-st[st[np].pre].step;
f2 = 1;
}
}
np = st[np].pre;
}
}
void solve() {
scanf("%d", &t);
while(t--) {
scanf("%d%s", &k, str);
init();
ans = tmp = 0;
int len = strlen(str);
for(int i = 0; i < len; i++)
extend(str[i]-'a');
printf("%lld\n", ans-tmp);
}
}
int main() {
solve();
}