MUV LUV EXTRA
给定一个无限循环小数的前 N 位,定义一个循环节的置信度为 ap − bl,其中 a, b 是给定的正整数系数,而 p 为这 N 位里包含该循环节的小数位数,l 为循环节长度,求所有可能的循环节中最大的置信度。
例如 1.0285714285714 中,0285714285714 和 428571 都是可能的循环节。
N ≤ 106
题解
枚举 p,之后用 Fail 算出最小的循环节。
倒着跑一遍 KMP 求出所有 Fail。
CO int N=1e7+10;
char s[N],t[N];
int fa[N];
void real_main(int64 a,int64 b){
scanf("%s",s+1);
int n=strlen(s+1),m=0;
for(int i=1;i<=n;++i)if(s[i]=='.')
m=n-i,reverse_copy(s+i+1,s+n+1,t+1);
int64 ans=a-b;
for(int i=2;i<=m;++i){
int j=fa[i-1];
while(j and t[j+1]!=t[i]) j=fa[j];
fa[i]=t[j+1]==t[i]?j+1:0;
ans=max(ans,a*i-b*(i-fa[i]));
}
printf("%lld
",ans);
}
int main(){
for(int64 a,b;scanf("%lld%lld",&a,&b)!=EOF;) real_main(a,b);
return 0;
}
Periods of Words
一个串是有限个小写字符的序列,特别的,一个空序列也可以是一个串. 一个串P是串A的前缀, 当且仅当存在串B, 使得 A = PB. 如果 |P|<|A| 并且 P 不是一个空串,那么我们说 P 是A的一个proper前缀. 定义Q 是A的周期, 当且仅当Q是A的一个proper 前缀并且A是QQ的前缀(不一定要是proper前缀). 比如串 abab 和 ababab 都是串abababa的周期. 串A的最大周期就是它最长的一个周期或者是一个空串(当A没有周期的时候), 比如说, ababab的最大周期是abab. 串abc的最大周期是空串. 给出一个串,求出它所有前缀的最大周期长度之和.
题解
https://www.cnblogs.com/jklover/p/10192299.html
这个找最长的周期显然还是只需要跳fail。注意到就算开始的fail大于一半肯定还是存在合法解的。
只需要沿着fail指针(失配边)往前跳,跳到第一个不为0的位置即可,可以路径压缩进行优化.
时间复杂度(O(K))。
co int K=1e6+1;
char s[K];
int fail[K];
int main()
{
int k;
read(k);
scanf("%s",s+1);
for(int i=1;i<k;++i)
{
int j=fail[i];
while(j&&s[j+1]!=s[i+1])
j=fail[j];
fail[i+1]=s[j+1]==s[i+1]?j+1:0;
}
ll ans=0;
for(int i=1;i<=k;++i)
{
if(fail[fail[i]])
fail[i]=fail[fail[i]];
if(fail[i])
ans+=i-fail[i];
}
printf("%lld
",ans);
return 0;
}