不需太多处理
hash一下直接暴枚吧。。
考虑这样两层循环
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i)
是不是很像筛法挖素数?可以证明复杂度是
O(N∗logN)
O
(
N
∗
l
o
g
N
)
的
然后就OK了
PS:可以加类似剪枝的优化
#include<bits/stdc++.h>
#define gt() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++)
#define pt(ch) (Top<1000000?St[Top++]=ch:(fwrite(St,1,1000000,stdout),St[(Top=0)++]=ch))
#define LL long long
#define __R register
using namespace std;
int Top;static char St[1000000],buf[1000000],*p1=buf,*p2=buf;
const int bas=(1e6)+7,maxn=(2e5)+5;
int n,a[maxn],cnt,p[maxn],Ans,id[maxn];LL L[maxn],R[maxn],Pow[maxn],c[maxn];
inline int read(){
int ret=0;char ch=gt();
while(ch<'0'||ch>'9') ch=gt();
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
return ret;
}
void write(int x){if(x<0) x=-x,pt('-');if(x>9) write(x/10);pt(x%10+'0');}
template<typename Tp>inline Tp Max(Tp x,Tp y){return x>y?x:y;}
int main(){
n=read();Pow[0]=1;
for(__R int i=1;i<=n;i++) L[i]=L[i-1]*bas+(a[i]=read()),Pow[i]=Pow[i-1]*bas;
for(__R int i=n;i;i--) R[i]=R[i+1]*bas+a[i];
for(__R int i=1;i<=n;i++){
if(n/i<Ans) break;//答案不会变好了
cnt=0;
for(__R int j=i;j<=n;j+=i) c[++cnt]=Max(L[j]-L[j-i]*Pow[i],R[j-i+1]-R[j+1]*Pow[i]);
sort(c+1,c+1+cnt),p[i]=unique(c+1,c+1+cnt)-c-1;
if(p[i]>Ans) Ans=p[i],id[id[0]=1]=i;else if(p[i]==Ans) id[++id[0]]=i;
}
write(Ans),pt(' '),write(id[0]),pt('\n');
for(__R int i=1;i<id[0];i++) write(id[i]),pt(' ');write(id[id[0]]),pt('\n');
fwrite(St,1,Top,stdout);
return 0;
}