题解
1.Q是S的前缀
2.Q!=S
3.S是QQ的前缀,且S可以等于QQ
4.从S中挖掉Q后剩下的部分与Q(s)的前半部分重合,也就是公共前后缀
5.要让Q尽可能长,就要让公共前后缀尽可能短(非零)
细节请看代码
解答一些疑惑:为什么不能直接求最短公共前后缀,而是要先求最大公共前后缀?
code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char s[1000005];
ll sps[1000005]={0};
inline void read(ll &x) {
x = 0;
ll flag = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')flag = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
x *= flag;
}
inline void write(ll x)
{
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
ll n;
read(n);
scanf("%s", s+1); // Keeping scanf for string input as it's not specified to change
ll it=0;
for(ll i=2;i<=n;i++)
{
while(it&&s[it+1]!=s[i]) it=sps[it];
if(s[it+1]==s[i]) sps[i]=++it;
}
ll ans=0;
for(ll i=2;i<=n;i++)
{
ll it=i;
while(sps[it]) it=sps[it];
if(it<sps[i]) sps[i]=it;//记忆化
ans+=i-it;
}
write(ans);
return 0;
}
标签:后缀,ll,POI2006,char,while,Periods,公共,P3435,getchar
From: https://www.cnblogs.com/pure4knowledge/p/18114288