[BZOJ 2081]Beads
Hash第一题……
这个题直接枚举串长Hash判断即可。不过,注意读题。
感觉Hash挺简单的。还有就是我用了wyy的生日做Hash种子辣!
代码:
/************************************************************** Problem: 2081 User: danihao123 Language: C++ Result: Accepted Time:5636 ms Memory:10904 kb ****************************************************************/ #include <cstdio> #include <set> #include <vector> using namespace std; typedef unsigned long long ull; const int maxn=200005; const ull x=200261; ull s[maxn]; ull sufHash[maxn],preHash[maxn],x_pow[maxn]; int n; inline void InitHash(){ register int i; for(i=n;i>=1;i--){ sufHash[i]=s[i]+sufHash[i+1]*x; } for(i=1;i<=n;i++){ preHash[i]=s[i]+preHash[i-1]*x; } x_pow[0]=1; for(i=1;i<=n;i++){ x_pow[i]=x*x_pow[i-1]; } } inline ull Hash(int i,int L){ return sufHash[i]-x_pow[L]*sufHash[i+L]; } inline ull FilpHash(int i,int L){ return preHash[i+L-1]-x_pow[L]*preHash[i-1]; } set<ull> S; vector<int> AnsList; int tot=0; inline void Check(int k){ register int i,ans=0; register ull h; S.clear(); for(i=1;(i+k-1)<=n;i+=k){ h=Hash(i,k)*FilpHash(i,k); if(!S.count(h)){ S.insert(h); ans++; } } if(ans>tot){ tot=ans; AnsList.clear(); AnsList.push_back(k); }else{ if(ans==tot) AnsList.push_back(k); } } int main(){ register int i,ans=0,maxv=0,cnt,temp; bool flag; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%llu",&s[i]); InitHash(); for(i=1;i<=n;i++){ Check(i); } printf("%d %d\n",tot,AnsList.size()); flag=false; for(i=0;i<AnsList.size();i++){ if(flag) putchar(' '); flag=true; printf("%d",AnsList[i]); } putchar('\n'); return 0; }