Description
Input
Output
Sample Input
样例一:
abababc
样例二:
isdashagayisdashagaydashisnotagaydashisnotagay
Sample Output
样例一:
6
样例二:
30
Data Constraint
思路
KMP + DP,考虑 KMP 中的 next[i],代表最大的 k(k != i) 使‘s[1]s[2]…s[k] == s[i – k + 1]s[i –
k]…s[i]’,那么我们设 f[i] 代表以 i 前缀 ‘s[1]s[2]…s[i]’ 内所有偶数子串出现的次数(包含本身),得
到:
?? = 1 + ?[????[?]] | ? % 2 == 0 ?[????[?]] | ? % 2 == 1
时间复杂度 O(n)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 200077
using namespace std;
char s[maxn],st[maxn],ch;
int next[maxn],len;
long long ans,f[maxn];
void get_next(char *st,int len)
{
memset(next,0,sizeof(next));
int j=0;
for(int i=2;i<=len;i++)
{
while(j>0 && st[j+1]!=st[i])j=next[j];
if(st[i]==st[j+1])j++;
next[i]=j;
}
}
int kmp(int l)
{
int j=0,sum=0;
for(int i=1;i<=len;i++)
{
while(j>0 && s[i]!=st[j+1])j=next[j];
if(s[i]==st[j+1])j++;
if(j==l)
{
sum++;
j=next[l];
}
}
return sum;
}
void get(int len)
{
for(int i=1;i<=len;i++)
st[i]=s[i];
}
void fin(int l,int r)
{
if(l+1>=r)return;
int mid=(l+r)/2;
get(2*mid);get_next(st,2*mid);f[mid]=kmp(2*mid);
if(f[mid]<f[l])fin(l,mid);
if(f[mid]>f[r])fin(mid,r);
}
int main()
{
ch=getchar();
while(ch<'a' || ch>'z')ch=getchar();
while('a'<=ch && ch<='z')s[++len]=ch,ch=getchar();
get_next(s,len);
for(int i=2;i<=len;i++)
{
if(i%2)f[i]=f[next[i]];else f[i]=f[next[i]]+1;
ans+=f[i];
}
printf("%lld",ans);
}