题目:
题目描述
老虎和蒜头是好朋友。
中秋节时,老虎收到了一个长度为 nn 的由小写字母构成的串 SS,老虎想要和蒜头一起分享这份喜悦。蒜头当然和老虎的想法不同,虽然蒜头也认为这很有意思,但蒜头更关心的是,如果我们现在可以在 SS 中修改一个字符,那么所有可能的周期长度是多少?
一个长度 1≤T<n1≤T<n 被称为字符串 SS 的周期,当且仅当对任意 1≤i≤n−T1≤i≤n−T ,都有 Si=Si+TSi=Si+T 。
输入格式
共一行,一个长度为 nn 的,只由小写字母构成的串 SS 。
输出格式
输出共两行。在第一行你应当输出可能的周期长度的个数 mm。不妨假设 c=⌈m105⌉c=⌈m105⌉ ,而所有可能的周期长度升序排列后为 l1,l2,…,lml1,l2,…,lm ,那么你应当输出 lc,l2c,…,l⌊mc⌋clc,l2c,…,l⌊mc⌋c 。
样例数据
样例一
input
abaabac
output
3
3 5 6
数据范围及限制
对于 100% 的数据,1≤n≤1071≤n≤107 。
对于 20% 的数据,n≤100n≤100 。
对于 40% 的数据,n≤2000n≤2000 。
对于 60% 的数据,n≤20000n≤20000 。
对于 80% 的数据,n≤5×105n≤5×105 。
对于另外 10% 的数据,字符串中只含a,b两种字符。
时间限制: 1s
空间限制: 512MB
思路:
60分的话就是n^2做法。
枚举周期,然后暴力判断就好了。
要注意要修改时不能只标记,要真的修改,不然会爆0。
还要注意第一段就要修改的情况,不考虑只有20分。
代码:
//by juruoZAR
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define maxn 20000
#define read(x) scanf("%d",&x);
int n;
char a[maxn+5];
char b[maxn+5];
int ans[maxn+5],cnt=0;
int main() {
scanf("%s",a+1);
n=strlen(a+1);
for(int i=1;i<=n;i++) b[i]=a[i];
for(int i=1;i<n;i++) {
int s=0;
for(int j=1;j<=n;j++) a[j]=b[j];
for(int j=1;j<=n-i;j++) {
if(a[j]!=a[j+i]) {
s++;
if(s>=2) goto END;
a[j+i]=a[j];
}
}
ans[++cnt]=i;
continue;
END:;
s=0;
for(int j=1;j<=n;j++) a[j]=b[j];
for(int j=1+i;j<=n-i;j++) {
if(a[j]!=a[j+i]) {
goto FLAG;
}
}
for(int j=1;j<=i;j++) {
if(j+i>n) break;
if(a[j]!=a[j+i]) s++;
}
if(s<2) ans[++cnt]=i;
FLAG:;
}
int c=(cnt-1)/(1e5)+1;
printf("%d\n",cnt);
for(int i=1;i*c<=cnt;i++) printf("%d ",ans[i]);
return 0;
}