LOJ2427

LOJ2427

不需太多处理
hash一下直接暴枚吧。。
考虑这样两层循环

for(int i=1;i<=n;i++)
   for(int j=i;j<=n;j+=i)

是不是很像筛法挖素数?可以证明复杂度是 O(NlogN) O ( N ∗ l o g N )
然后就OK了
PS:可以加类似剪枝的优化

#include
#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');}
templateinline 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/ibreak;//答案不会变好了
      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;i0];i++) write(id[i]),pt(' ');write(id[id[0]]),pt('\n');
    fwrite(St,1,Top,stdout);
    return 0; 
}

你可能感兴趣的:(哈希,均摊,LOJ)