ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ARC060F口胡

2022-04-27 19:01:57  阅读:136  来源: 互联网

标签:gcd int 原串 循环 ARC060F include neq


诈 骗 题

我一直以为是 DP 什么的有性质,结果发现是道诈骗题,什么性质都没有。

首先特判掉全 \(a\) 串。有一个结论:全场最佳只有可能是两个字符串组成的。

随便证明一下。设 \(S[i]\) 是长度为 \(i\) 的前缀,\(T[i]\) 是长度为 \(i\) 的后缀。

首先对于 \(S[i](2i\geq n)\) 和 \(T[i](n\geq 2i-2)\)。的都不用管,这些肯定不是原串的循环。

那么在我们的讨论中,前缀和后缀的长度不可能超过 \(n\) 的一半。

找到一个分界点 \(i\)。如果 \(S[i]\) 和 \(T[i+1]\) 都是坏的,那么往右或往左移一格一定是好的。

证明:尝试说明若 \(S[i]\) 是原串的循环则 \(S[i+1]\) 一定不是原串的循环。

首先全 \(a\) 串已经被我们判掉了。设一个 \(i=ax,i+1=by\)。那么 \(\gcd(x,y)\) 一定等于 \(1\)。

若不等于 \(1\),那么说明 \(\gcd(x,y)\neq 1\),也说明 \(\gcd(i,i+1)\neq 1\),而这不可能。

然后,正反跑两遍 KMP 判断是不是循环就完了。。。

upd:草,居然是对的

#include<cstring>
#include<cstdio>
const int M=5e5+5;
int n,F[M],G[M];char s[M],t[M];
inline bool check(){
	for(int i=2;i<=n;++i)if(s[i]!=s[i-1])return false;return true;
}
inline bool check(int*fail,const int&x){
	if(fail[x]*2<x)return true;return x%(x-fail[x]);
}
signed main(){
	int sum(0);
	scanf("%s",s+1);n=strlen(s+1);if(check())return printf("%d\n1",n),0;for(int i=1;i<=n;++i)t[n-i+1]=s[i];
	for(int j=0,i=2;i<=n;++i){
		while(j&&s[i]!=s[j+1])j=F[j];if(s[i]==s[j+1])++j;F[i]=j;
	}
	for(int j=0,i=2;i<=n;++i){
		while(j&&t[i]!=t[j+1])j=G[j];if(t[i]==t[j+1])++j;G[i]=j;
	}
	if(check(F,n))return printf("1\n1"),0;
	for(int i=1;i<n;++i)if(check(F,i)&&check(G,n-i))++sum;printf("2\n%d",sum);
}

标签:gcd,int,原串,循环,ARC060F,include,neq
来源: https://www.cnblogs.com/lmpp/p/16200152.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有