zoukankan      html  css  js  c++  java
  • LUOGUP3498 [POI2010]KOR-Beads (哈希)

    传送门

    解题思路

    这是一道上周的考试题。。。当时考的时候看了一眼,"呀,这不是调和级数,nlogn么!!!" ,然后一写就写了个n^2的。。。。结果边界还弄错40分滚蛋了。。正解就是正着求一遍hash,倒着求一遍hash,再求个逆元,O(nlogn)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    
    using namespace std;
    const int MAXN = 200005;
    const int mod = 19260817;
    typedef long long LL;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int n,a[MAXN],base,cnt,ans,Ans[MAXN],num;
    int hsh[MAXN],hsh_[MAXN];
    int inv[MAXN],c[20000000];
    
    int fast_pow(int x,int y){
        int ret=1;
        for(;y;y>>=1){
            if(y&1) ret=(LL)ret*x%mod;
            x=(LL)x*x%mod;
        }
        return ret;
    }
    
    int main(){
    //    freopen("bead.in","r",stdin);
    //    freopen("bead.out","w",stdout);
        n=rd();base=n+1;inv[0]=1;int now=1;
        for(int i=1;i<=n;i++) {
            now=(LL)now*base%mod;a[i]=rd();inv[i]=fast_pow(now,mod-2);
            hsh[i]=hsh[i-1]+(LL)now*a[i]%mod;hsh[i]%=mod;
        }now=1;
        for(int i=n;i;i--) {
            now=(LL)now*base%mod;
            hsh_[i]=hsh_[i+1]+(LL)a[i]*now%mod;
            hsh_[i]%=mod;
        }
    //    cout<<hsh_[1]<<endl;cout<<inv[n]<<endl;    
        int tmp,tmp_;
        for(int i=1;i<=n;i++){
            cnt=0;
            if(n/i<ans) break;
            for(register int j=i;j<=n;j+=i) {
                if(j>n) break;
                tmp=((hsh[j]-hsh[j-i])%mod+mod)%mod;
                tmp_=((hsh_[j-i+1]-hsh_[j+1])%mod+mod)%mod;
                tmp=(LL)tmp*inv[j-i]%mod;tmp_=(LL)tmp_*inv[n-j]%mod;
                if(c[tmp]==i && c[tmp_]==i) continue;
                c[tmp]=c[tmp_]=i;cnt++;
            }    
            if(cnt>ans) {ans=cnt;num=0;Ans[++num]=i;}
            else if(cnt==ans) Ans[++num]=i;
        }
        printf("%d %d
    ",ans,num);
        for(int i=1;i<=num;i++) printf("%d ",Ans[i]);
        return 0;
    }
    
    /*
    21
    1 1 1 2 2 2 3 3 3 1 2 3 3 1 2 2 1 3 3 2 1
    */
    View Code
  • 相关阅读:
    vue使用Highcharts图表
    Laya 骨骼动画播放
    unity3d学习笔记
    unity学习笔记
    Laya本地存储对象,读取上来之后没有类方法了
    Laya2学习笔记
    Laya vscode f5断点调试开启
    fairyGUI学习笔记
    使用docker安装swoole环境
    docker学习笔记
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9703403.html
Copyright © 2011-2022 走看看