• 解题:POI 2010 Beads


    题面

    正反各做一遍哈希来判断,然后在两个哈希值里取一个$max/min$做哈希值,然后每次把子串们的哈希插进$set$里,最后统计集合大小,就可以优秀地在$O(nlog^2$ $n)$中出解了

    然后我觉得这样太没有理想了,就写了一个挂链哈希表,结果跑的贼慢。。。

    我挂链时的区分方法是换模数再模出一个新值,然后这样做的时候注意要和哈希表的基数和模数区分开

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=200050,M=2500;
     6 const long long bs=1009,md=2333;
     7 const long long bas=203339,mod=2147483647;
     8 long long num[N],hah[N][2],huh[N][2],pw[N][2],val[N];
     9 int p[M],nxt[N],outp[N];
    10 int n,pos,cnt,ans;
    11 long long Ghash(int l,int r,int t)
    12 {
    13     long long mdd=t?mod:md;
    14     long long h1=((hah[r][t]-hah[l-1][t]*pw[r-l+1][t])%mdd+mdd)%mdd;
    15     long long h2=((huh[l][t]-huh[r+1][t]*pw[r-l+1][t])%mdd+mdd)%mdd;
    16     return max(h1,h2);
    17 }
    18 bool Fhash(long long has,long long hsh)
    19 {
    20     for(int i=p[has%md];i;i=nxt[i])
    21         if(val[i]==hsh) return true;
    22     return false;
    23 }
    24 void Ihash(long long has,long long hsh)
    25 {
    26     if(Fhash(has,hsh)) return ;
    27     nxt[++cnt]=p[pos=has%md];
    28     val[cnt]=hsh,p[pos]=cnt;
    29 }
    30 int main ()
    31 {
    32     scanf("%d",&n),pw[0][0]=pw[0][1]=1;
    33     for(int i=1;i<=n;i++)
    34     {
    35         scanf("%lld",&num[i]);
    36         pw[i][0]=pw[i-1][0]*bs%md;
    37         pw[i][1]=pw[i-1][1]*bas%mod;
    38     }
    39     for(int i=1;i<=n;i++) 
    40     {
    41         hah[i][0]=(hah[i-1][0]*bs+num[i])%md;
    42         hah[i][1]=(hah[i-1][1]*bas+num[i])%mod;
    43     }
    44     for(int i=n;i;i--) 
    45     {
    46         huh[i][0]=(huh[i+1][0]*bs+num[i])%md;
    47         huh[i][1]=(huh[i+1][1]*bas+num[i])%mod;
    48     }
    49     for(int i=1;i<=n;i++)
    50     {
    51         memset(p,0,sizeof p); cnt=0;
    52         for(int j=1;j<=n-i+1;j+=i)
    53             Ihash(Ghash(j,j+i-1,0),Ghash(j,j+i-1,1));
    54         if(cnt>ans) ans=cnt,outp[outp[0]=1]=i;
    55         else if(cnt==ans) outp[++outp[0]]=i;
    56     }
    57     printf("%d %d
    ",ans,outp[0]);
    58     for(int i=1;i<=outp[0];i++)
    59         printf("%d ",outp[i]);
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    Win32 程序开发入门:一个最简单的Win32程序
    DirectShow 进行视频预览和录制
    DirectShow 获取音视频输入设备列表
    (原)关于人民币找零钱的问题
    (转)The C10K problem翻译
    (原)kenel开机logo的制作
    (原)关于udp的socket发送数据耗时的问题探讨
    (转)x264的一些参数设置对编码效率的影响
    (原)关于获取ffmpeg解析rtsp流sdp中带有sps,pps的情况
    (转)java 层调用Jni(Ndk) 持久化c c++ 对象
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9725259.html
Copyright © 2020-2023  润新知