bzoj2081: [Poi2010]Beads

传送门
哈希被卡了。孟戴章峥
直接暴力+哈希驶过去,但是模数要取好。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define bas 200019
#define mo 1000000009
#define ll long long
using namespace std;
int n,ans,a[bas],sta[bas],top;
ll hs1[bas],hs2[bas],power[bas];
namespace Hash{
    struct node{
        int val;
        bool flag;
        node *nxt;
        node(int _,node *__):
            val(_),flag(0),nxt(__){}
    }*head[bas];
    int tim[bas],T;
    void pre(){T++;}
    bool& hash(int val){
        int pos=val%bas;
        if (tim[pos]!=T) tim[pos]=T,head[pos]=0x0;
        for (node *tmp=head[pos];tmp;tmp=tmp->nxt)
            if (tmp->val==val) return tmp->flag;
        return (head[pos]=new node(val,head[pos]))->flag; 
    }
}
int main(){
    using namespace Hash;
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=n;i++) hs1[i]=(hs1[i-1]*bas+a[i])%mo;
    for (int i=n;i>=1;i--) hs2[i]=(hs2[i+1]*bas+a[i])%mo;
    for (int i=power[0]=1;i<=n;i++) power[i]=power[i-1]*bas%mo;
    for (int i=1;i<=n;i++){
        int tot=0;
        pre();
        for (int j=i;j<=n;j+=i){
            int l=j-i+1,r=j;
            ll tmp1=(hs1[r]-hs1[l-1]*power[r-l+1]%mo+mo)%mo;
            ll tmp2=(hs2[l]-hs2[r+1]*power[r-l+1]%mo+mo)%mo;
            bool &flag=hash(tmp1*tmp2%mo);
            if (!flag) ++tot;
            flag=1; 
        }
        if (tot>ans) ans=tot,top=0;
        if (tot==ans) sta[++top]=i;
    }
    printf("%d %d\n",ans,top);
    for (int i=1;i<=top;i++){
        printf("%d",sta[i]);
        if (i!=top) printf(" ");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值