zoukankan      html  css  js  c++  java
  • 字符串算法复习

    字符串算法复习

     

    声明:

    由于本人较弱,并不能保证以下内容的100%正确

    欢迎大佬来挑错

    Hash

    自然溢出hash

    单模数hash

    双模数hash

    挂链hash

    Trie

    普通Trie

    可持久化Trie

    Kmp

    扩展Kmp(不会)

    后缀数组

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cassert>
     5 using namespace std;
     6 const int maxn=1000009;
     7 
     8 int n;
     9 
    10 char s[maxn];
    11 int sa[maxn],c[maxn];
    12 int t1[maxn<<1],t2[maxn<<1];
    13 void BuildSA(int m){
    14     int *x=t1,*y=t2;
    15     
    16     for(int i=1;i<=m;++i)c[i]=0;
    17     for(int i=1;i<=n;++i)c[x[i]=s[i]]++;
    18     for(int i=2;i<=m;++i)c[i]+=c[i-1];
    19     for(int i=n;i>=1;--i)sa[c[x[i]]--]=i;
    20     
    21     for(int k=1;k<n;k<<=1){
    22         int p=0;
    23         for(int i=n-k+1;i<=n;++i)y[++p]=i;
    24         for(int i=1;i<=n;++i)if(sa[i]-k>0)y[++p]=sa[i]-k;
    25         
    26         for(int i=1;i<=m;++i)c[i]=0;
    27         for(int i=1;i<=n;++i)c[x[y[i]]]++;
    28         for(int i=2;i<=m;++i)c[i]+=c[i-1];
    29         for(int i=n;i>=1;--i)sa[c[x[y[i]]]--]=y[i];
    30         
    31         swap(x,y);
    32         x[sa[1]]=p=1;
    33         for(int i=2;i<=n;++i){
    34             if((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+k]==y[sa[i-1]+k]))x[sa[i]]=p;
    35             else x[sa[i]]=++p;
    36         }
    37         if(p>=n)break;
    38         m=p;
    39     }
    40 }
    41 
    42 int main(){
    43     scanf("%s",s+1);
    44     n=strlen(s+1);
    45     BuildSA(10000);
    46     
    47     for(int i=1;i<=n;++i)printf("%d ",sa[i]);
    48     return 0;
    49 }

    后缀自动机

     Menci的链接

    https://oi.men.ci/suffix-automaton-notes/

    写得很清楚

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=1000009;
     6 
     7 
     8 int n;
     9 long long ans=0;
    10 char s[maxn];
    11 
    12 int nn=1,last=1;
    13 int par[maxn<<1]={0};
    14 int siz[maxn<<1]={0};
    15 int dis[maxn<<1]={0};
    16 int ch[maxn<<1][26]={0};
    17 void BuildSAM(int c){
    18     int p=last,np=++nn;
    19     last=np;siz[np]=1;dis[np]=dis[p]+1;
    20     
    21     for(;(p!=0)&&(!ch[p][c]);p=par[p])ch[p][c]=np;
    22     if(!p){
    23         par[np]=1;
    24     }else{
    25         int q=ch[p][c];
    26         if(dis[q]==dis[p]+1){
    27             par[np]=q;
    28         }else{
    29             int nq=++nn;
    30             for(int i=0;i<26;++i)ch[nq][i]=ch[q][i];
    31             dis[nq]=dis[p]+1;
    32             par[nq]=par[q];
    33             par[q]=par[np]=nq;
    34             for(;ch[p][c]==q;p=par[p])ch[p][c]=nq;
    35         }
    36     }
    37 }
    38 
    39 int c[maxn<<1];
    40 int sa[maxn<<1];
    41 void Dp(){
    42     for(int i=1;i<=nn;++i)c[dis[i]]++;
    43     for(int i=1;i<=nn;++i)c[i]+=c[i-1];
    44     for(int i=1;i<=nn;++i)sa[c[dis[i]]--]=i;
    45     for(int i=nn;i>=1;--i){
    46         int x=sa[i];
    47         siz[par[x]]+=siz[x];
    48         if(siz[x]!=1){
    49             ans=max(ans,1LL*siz[x]*dis[x]);
    50         }
    51     }
    52 }
    53 
    54 int main(){
    55     scanf("%s",s+1);
    56     n=strlen(s+1);
    57     for(int i=1;i<=n;++i)BuildSAM(s[i]-'a');
    58     
    59     Dp();
    60     cout<<ans<<endl;
    61     return 0;
    62 }

    广义后缀自动机

    2780: [Spoj]8093 Sevenk Love Oimaster

    4566: [Haoi2016]找相同字符

    AC自动机

    2754: [SCOI2012]喵星球上的点名

    manacher

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=30000000;
     6 
     7 int n;
     8 int ans=0;
     9 char T[maxn];
    10 
    11 char s[maxn];
    12 int p[maxn];
    13 void Manacher(int n){
    14     int mxpla=0,mxlen=0;
    15     for(int i=1;i<=n;++i){
    16         if(mxpla+mxlen>i){
    17             p[i]=min(mxpla+mxlen-i,p[2*mxpla-i]);
    18         }
    19         while(s[i-p[i]]==s[i+p[i]])++p[i];
    20         ans=max(ans,p[i]*2-1); 
    21         if(i+p[i]>mxpla+mxlen){
    22             mxpla=i;mxlen=p[i];
    23         }
    24     }
    25 }
    26 
    27 int main(){
    28     scanf("%s",T+1);
    29     n=strlen(T+1);
    30     int len=0;
    31     s[++len]='*';
    32     for(int i=1;i<=n;++i){
    33         s[++len]=T[i];
    34         s[++len]='*';
    35     }
    36     s[++len]='#';
    37     Manacher(len);
    38     
    39     cout<<(ans>>1)<<endl;
    40     return 0;
    41 }
  • 相关阅读:
    Typekit在线字库及使用方法
    SVG基础图形和D3.js
    CSS3 媒体查询@media 查询(响应式布局)
    Bootstrap 栅格系统(布局)
    CSS——图片替换方法:Fahrner图片替换法(FIR)
    CSS sprites(css 精灵):将小图标整合到一张图片上
    [html]点击button后画面被刷新原因:未设置type="button"
    [java]No qualifying bean of type 解决方法
    [eclipse]eclipse设置条件断点Breakpoint Properties
    Intent的setFlag和addFlag有什么区别?
  • 原文地址:https://www.cnblogs.com/zzyer/p/8965981.html
Copyright © 2011-2022 走看看