[BZOJ 2081]POI 2010 Beads

练暴力的题目。。。

直接枚举长度,计算答案,hash判重。

复杂度其实和调和级数有关,大概就是O(n*ln(n))(笔者偷懒判重直接用排序写了,水过了。。。偷笑

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAX=(1e9)+9,Maxn=200005;
int po[Maxn],hash[Maxn],rhash[Maxn],a[Maxn],p[Maxn];
int n,i,j,t,dig[Maxn],m,ans,cnt;

int main(){
  scanf("%d",&n);
  for (i=1,po[0]=1;i<=n;i++) po[i]=po[i-1]*MAX;
  for (i=1;i<=n;i++) scanf("%d",&a[i]);
  for (i=1;i<=n;i++) hash[i]=hash[i-1]*MAX+a[i];
  for (i=n;i>0;i--) rhash[i]=rhash[i+1]*MAX+a[i];
  for (i=1;i<=n;i++){
  	for (j=1,t=0;j+i-1<=n;j+=i){
  	  if (hash[j+i-1]-hash[j-1]*po[i] < rhash[j]-rhash[j+i]*po[i])
  	  	p[t++]=hash[j+i-1]-hash[j-1]*po[i];
  	  else
  	    p[t++]=rhash[j]-rhash[j+i]*po[i];
  	}
  	sort(p,p+t);
  	m=unique(p,p+t)-p;
  	if (m==ans) dig[++cnt]=i;
  	if (m>ans) ans=m, dig[cnt=1]=i;
  }
  printf("%d %d\n",ans,cnt);
  for (i=1;i<cnt;i++) printf("%d ",dig[i]);
  printf("%d\n",dig[cnt]);
  return 0;
}


你可能感兴趣的:(poi,hash,2010,暴力)