Problem J,Problem
Problem J,Problem
You’ll be given a string S and an integer K. You have to find the number of non
super-boring substring inside S. A substring is called super-boring if it contains any
palindromic substring of length ≥ K inside it.
For example, if S = “ababba” and K = 3, then the substring “abab” is a super-boring
substring because it contains a palindrome “aba” whose length is ≥ 3. But the substring
“bba” is a valid non super-boring substring.
Find the number of substrings which are not super-boring. Two substrings are considered
different only if their starting or ending positions are different.
Input Specification
The first line of input contains an integer T, denoting the number of test cases. The first
line of each test cases contains an integer K and the next line contains the string S
consisting of lower case English alphabets.
Constraints
1 ≤ T ≤ 100
K ≤ |S| ≤ 10
5
Sum of |S| over all test cases <= 10
6
Note: Here |S| denotes the length of the string S.
Output Specification
For each test case you have to print the number of non super-boring substring of the
string S.
Statements
Input Output
3
3
bababe
4
abcbbcbc
3
aabacecc
12
27
20
题意:
给你一个字符串,求区间内不包含长度k以上的回文串的子串个数
题解:
马拉车先求出回文长度,之后每个字符找过去,易证马拉车的回文半径-1就是字符串的回文长度,然后只需要找符合k的最短长度,如果是不同奇偶的话就是+1,那么在这个字符串前面有(i+1)/2-len/2个字符,这些字符就是包括长度至少为k的子串,那么我们就把他加到树状数组中,然后树状数组记录的是最大值,就代表以pos为结尾的子串,含有长度为k的回文串的子串有多少个
举个例子:
假设有asdfgfzxc这么一个字符串,k=3,很明显fgf是满足条件的,那么在后一个f之后便放到树状数组中4代表从6这个位置开始有4个满足要求的回文串,z,x,c这些位置都要减4.
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000050
#define ll long long
char s[maxn];
char ss[2*maxn];
int p[2*maxn];
void manacher(char s[],int len)
{
int i,j,len1;
for(i=0;i<2*len+2;i++)ss[i]='#';
for(i=0;i<len;i++)ss[i*2+2]=s[i];
len1=len*2+1;ss[0]='$';
int mx=0,id=0;
int ans=0;
for(int i=0;i<len1;i++){
p[i]=mx>i?min(p[2*id-i],mx-i ):1;
while(ss[i+p[i] ]==ss[i-p[i] ] )p[i]++;
if(ans<p[i])ans=p[i];
if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
}
}
int sum[maxn];
int mlen;
int lowbit(int x)
{
return x&(-x);
}
void add(int pos,int val)
{
for(int i=pos;i<=mlen;i+=lowbit(i))
sum[i]=max(sum[i],val);
}
ll query(int pos)
{
ll ans=0;
for(int i=pos;i>=1;i-=lowbit(i))
ans=max(ans,(ll)sum[i]);
return ans;
}
vector<int>vec[500005];
int len[500005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(sum,0,sizeof(sum));
int k;
scanf("%d",&k);
scanf("%s",s);
manacher(s,strlen(s));
mlen=strlen(ss);
ll ans=0;
for(int i=2;i<=mlen;i++)
{
int len=p[i]-1;
if(len<k)
continue;
if((len+k)%2==0)
len=k;
else
len=k+1;
int val=(i+1)/2-len/2;
int pos=val+len-1;
add(pos,val);
}
int n=strlen(s);
for(int i=1;i<=n;i++)
{
int num=query(i);
ans+=i-num;
}
printf("%lld\n",ans);
}
return 0;
}
相关文章
- 暂无相关文章
用户点评