[BZOJ 2081]Beads
转载请注明出处:http://danihao123.is-programmer.com/
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;
}
评论 (0)