string string string
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 337 Accepted Submission(s): 75
Problem Description
Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle Mao was so lazy that he left the problem to you. I hope you can give him a solution.
Given a string s, we define a substring that happens exactly k times as an important string, and you need to find out how many substrings which are important strings.
Given a string s, we define a substring that happens exactly k times as an important string, and you need to find out how many substrings which are important strings.
Input
The first line contains an integer
T
(
T≤100
) implying the number of test cases.
For each test case, there are two lines:
the first line contains an integer k ( k≥1 ) which is described above;
the second line contain a string s ( length(s)≤105 ).
It's guaranteed that ∑length(s)≤2∗106 .
For each test case, there are two lines:
the first line contains an integer k ( k≥1 ) which is described above;
the second line contain a string s ( length(s)≤105 ).
It's guaranteed that ∑length(s)≤2∗106 .
Output
For each test case, print the number of the important substrings in a line.
Sample Input
2 2 abcabc 3 abcabcabcabc
Sample Output
6 9
Source
Recommend
后缀数组预处理出高度数组H,然后 用区间最小值-两端的最大值统计即可
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
const int MX = 2e5 + 20;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
char s[MX];
int SA[MX], R[MX], H[MX];
int wa[MX], wb[MX], wv[MX], wc[MX];
bool cmp(int *r, int a, int b, int l) {
return r[a] == r[b] && r[a + l] == r[b + l];
}
void Suffix(char *r, int m = 128) {
int n = strlen(r) +1;
int i, j, p, *x = wa, *y = wb, *t;
for(i = 0; i < m; i++) wc[i] = 0;
for(i = 0; i < n; i++) wc[x[i] = r[i]]++;
for(i = 1; i < m; i++) wc[i] += wc[i - 1];
for(i = n - 1; i >= 0; i--) SA[--wc[x[i]]] = i;
for(j = 1, p = 1; p < n; j *= 2, m = p) {
for(p = 0, i = n - j; i < n; i++) y[p++] = i;
for(i = 0; i < n; i++) if(SA[i] >= j) y[p++] = SA[i] - j;
for(i = 0; i < n; i++) wv[i] = x[y[i]];
for(i = 0; i < m; i++) wc[i] = 0;
for(i = 0; i < n; i++) wc[wv[i]]++;
for(i = 1; i < m; i++) wc[i] += wc[i - 1];
for(i = n - 1; i >= 0; i--) SA[--wc[wv[i]]] = y[i];
for(t = x, x = y, y = t, p = 1, x[SA[0]] = 0, i = 1; i < n; i++) {
x[SA[i]] = cmp(y, SA[i - 1], SA[i], j) ? p - 1 : p++;
}
}
int k = 0; n--;
for(i = 0; i <= n; i++) R[SA[i]] = i;
for(i = 0; i < n; i++) {
if(k) k--;
j = SA[R[i] - 1];
while(r[i + k] == r[j + k]) k++;
H[R[i]] = k;
}
}
int mi[MX];
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int n)
{
int lx,i;
while(x <=n){
mi[x] = H[x];
lx = lowbit(x);
for(int i = 1; i < lx; i<<=1)
mi[x] = min(mi[x],mi[x-i]);
x += lowbit(x);
}
}
int query(int x, int y)
{
int ans = INF;
while(y >= x){
ans = min(H[y],ans);
y--;
for(;y-lowbit(y)>=x; y -= lowbit(y)){
ans= min(mi[y],ans);
}
}
return ans;
}
int main(){
#ifdef __LOCAL__
freopen("input.txt","r",stdin);
#endif // __LOCAL__
int T;
scanf("%d",&T);
while(T--){
int k;
scanf("%d",&k);
scanf("%s",s+1);
int n = strlen(s+1);
Suffix(s+1);
for(int i = 1; i <= n; i++)
update(i,n);
// cout<<s+1<<endl;
// for(int i = 1; i <= n; i++)
// cout<<H[i]<<" ";
// cout<<endl;
LL ans = 0;
for(int i = 1; i+k-1 <= n; i++){
int minx = i+1 <= i+k-1? query(i+1,i+k-1) : n-SA[i];
int maxx = 0;
if(i > 1) maxx = max(maxx,H[i]);
if(i+k-1 < n) maxx = max(maxx,H[i+k]);
if(minx > maxx) ans += minx - maxx;
// cout<<minx<<" "<<maxx<<endl;
}
cout<<ans<<endl;
}
return 0;
}