• 字符串题模板集合


    后缀数组

    //by zzq
    //改进后的后缀数组模板 
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    #define SZ 2333333
    #define P 20
    int n,k,sa[SZ],t[SZ],rank[SZ],qzh[SZ],tmpsa[SZ],tmpr[SZ],h[SZ];
    char s[SZ];
    bool same(int a,int b,int p) {return t[a]==t[b]&&t[a+p]==t[b+p];}
    void getsa(int m=500)
    {
        s[++n]=0;
        for(int i=0;i<n;i++) rank[i]=s[i], ++qzh[rank[i]];
        for(int i=1;i<m;i++) qzh[i]+=qzh[i-1];
        for(int i=n-1;i>=0;i--) sa[--qzh[rank[i]]]=i;
        for(int j=1;j<=n;j<<=1)
        {
            int cur=-1;
            for(int i=n-j;i<n;i++) tmpsa[++cur]=i;
            for(int i=0;i<n;i++) if(sa[i]>=j) tmpsa[++cur]=sa[i]-j;
            for(int i=0;i<n;i++) tmpr[i]=rank[tmpsa[i]];
            for(int i=0;i<m;i++) qzh[i]=0;
            for(int i=0;i<n;i++) ++qzh[tmpr[i]];
            for(int i=1;i<m;i++) qzh[i]+=qzh[i-1];
            for(int i=n-1;i>=0;i--) t[i]=rank[i], sa[--qzh[tmpr[i]]]=tmpsa[i];
            m=0;
            for(int i=0;i<n;i++)
                rank[sa[i]]=(i>0&&same(sa[i],sa[i-1],j))?m:++m;
            ++m;
        }
        for(int i=0;i<n;i++) rank[sa[i]]=i;
        int p=0;
        for(int i=0;i<n;i++)
        {
            if(p) --p;
            int ls=sa[rank[i]-1];
            while(s[ls+p]==s[i+p]) p++;
            h[rank[i]]=p;
        }
        --n;
        for(int i=1;i<=n;i++) sa[i-1]=sa[i];
        for(int i=0;i<n;i++) rank[sa[i]]=i;
        for(int i=2;i<=n;i++) h[i-1]=h[i];
        h[n]=sa[n]=0;
    }
    int log2[SZ],minn[SZ][P];
    void getst()
    {
        for(int i=0;i<n;i++) minn[i][0]=h[i];
        for(int i=1;i<=n;i++)
        {
            int t=0;
            while((1<<t)<=i) ++t;
            log2[i]=t-1;
        }
        for(int j=1;j<P;j++)
        {
            for(int i=0;i<n;i++)
            {
                if(i+(1<<j)<=n) minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);
                else minn[i][j]=-2333;
            }
        }
    }
    int gmin(int a,int b)
    {
        int l2=log2[b-a+1];
        return min(minn[a][l2],minn[b-(1<<l2)+1][l2]);
    }
    int lcp(int a,int b)
    {
        if(a==b) return n-a;
        if(rank[a]>rank[b]) swap(a,b);
        return gmin(rank[a]+1,rank[b]);
    }
    int main()
    {
        scanf("%s",s);
        n=strlen(s); getsa(); getst();
        while(1)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d
    ",lcp(a,b));
        }
    }

    hash+kmp(搭配风味更佳)

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <algorithm>
    using namespace std;
    #define SZ 2333333
    typedef long long ll;
    ll MOD=1000000007,cm[SZ],cmn[SZ];
    ll qp(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%MOD;
            a=a*a%MOD; b>>=1;
        }
        return ans;
    }
    struct HashKMP
    {
    char s[SZ+1]; int n;
    ll hash[SZ+1];
    void pre()
    {
        n=strlen(s);
        for(int i=n-1;i>=0;i--) hash[i]=(hash[i+1]+cm[n-1-i]*(s[i]-'a'+1)%MOD)%MOD;
    }
    ll ghash(int l,int r)
    {
        return ((hash[l]-hash[r+1])*cmn[n-1-r]%MOD+MOD)%MOD;
    }
    int next[SZ+3];
    void gnext()
    {
        next[0]=-1;
        int j=-1;
        for(int i=1;s[i];i++)
        {
            while(j!=-1&&s[i]!=s[j+1]) j=next[j];
            if(s[i]==s[j+1]) ++j;
            next[i]=j;
        }
    }
    void kmp(char* a)
    {
        int j=-1;
        for(int i=0;a[i];i++)
        {
            while(j!=-1&&s[j+1]!=a[i]) j=next[j];
            if(s[j+1]==a[i]) ++j;
            //do sth
            printf("%d w %d
    ",i,j);
        }
    }
    }ha;
    void getcm()
    {
        cm[0]=cmn[0]=1; ll gg=qp(31,MOD-2);
        for(int i=1;i<=1234567;i++) cm[i]=cm[i-1]*31%MOD;
        for(int i=1;i<=1234567;i++) cmn[i]=cmn[i-1]*gg%MOD;
    }
    
    char b[SZ+3];
    int main()
    {
        getcm();
        scanf("%s",ha.s);
        ha.pre();
        scanf("%s",b);
        ha.gnext();
        ha.kmp(b);
    }

    后缀自动机+序列自动机

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    int MOD=998244353;
    #define SZ 4008
    #define S 26 //字符集
    struct AM
    {
    int rot,ch[SZ][S],C,cnt[SZ];
    };
    struct SeqAM: public AM
    {
    int par[SZ],lst[S];
    SeqAM()
    {
        C=rot=1;
        for(int i=0;i<S;i++) lst[i]=rot;
    }
    void ins(char c)
    {
        ++C; par[C]=lst[c];
        for(int i=0;i<S;i++)
        {
            for(int g=lst[i];g&&!ch[g][c];g=par[g]) ch[g][c]=C;
        }
        lst[c]=C;
    }
    void getcnt()
    {
        for(int i=1;i<=C;i++) cnt[i]=1;
        for(int i=C;i>=1;i--)
        {
            for(int j=0;j<S;j++) cnt[i]+=cnt[ch[i][j]], cnt[i]%=MOD;
        }
    }
    }SeqA,SeqB;
    struct SufAM: public AM
    {
    int ml[SZ],fail[SZ],lst,cl,qzh[SZ],od[SZ];
    SufAM() {C=lst=rot=1; cl=0;}
    void ins(char c)
    {
        int x=++C,len=++cl,p=lst;
        lst=x; ml[x]=len;
        for(;p&&!ch[p][c];p=fail[p]) ch[p][c]=x;
        if(!p) fail[x]=rot;
        else if(ml[ch[p][c]]==ml[p]+1) fail[x]=ch[p][c];
        else
        {
            int chh=ch[p][c],cm=++C;
            ml[cm]=ml[p]+1; fail[cm]=fail[chh];
            for(int i=0;i<S;i++) ch[cm][i]=ch[chh][i];
            fail[chh]=fail[x]=cm;
            for(;ch[p][c]==chh;p=fail[p]) ch[p][c]=cm;
        }
    }
    void getcnt()
    {
        for(int i=0;i<SZ;i++) qzh[i]=0;
        for(int i=1;i<=C;i++) qzh[ml[i]]++;
        for(int i=1;i<SZ;i++) qzh[i]+=qzh[i-1];
        for(int i=1;i<=C;i++) od[qzh[ml[i]]--]=i;
        for(int i=1;i<=C;i++) cnt[i]=1;
        for(int i=C;i>=1;i--)
        {
            for(int j=0;j<S;j++) cnt[od[i]]+=cnt[ch[od[i]][j]], cnt[od[i]]%=MOD;
        }
    }
    }SufA,SufB;

    AC自动机

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    #define SZ 1000099
    int rot=1,ch[SZ][29],fail[SZ],cnt[SZ],e=1;
    void insert(char* s)
    {
        int cur=rot;
        for(int i=0;s[i];i++)
        {
            int c=s[i]-'a';
            if(!ch[cur][c]) ch[cur][c]=++e;
            cur=ch[cur][c];
        }
        cnt[cur]++;
    }
    int qs[SZ],h=0,t=0;
    void bfail()
    {
        h=t=0; fail[rot]=rot;
        for(int i=0;i<26;i++)
        {
            if(!ch[rot][i]) 
            {
                ch[rot][i]=rot; continue;
            }
            fail[ch[rot][i]]=rot;
            qs[t++]=ch[rot][i];
        }
        while(h!=t)
        {
            int cur=qs[h++];
            for(int c=0;c<26;c++)
            {
                if(!ch[cur][c]) ch[cur][c]=ch[fail[cur]][c];
                else
                {
                    fail[ch[cur][c]]=ch[fail[cur]][c];
                    qs[t++]=ch[cur][c];
                }
            }
        }
    }
    int match(char* s)
    {
        int cur=rot,ans=0;
        for(int i=0;s[i];i++)
        {
            int c=s[i]-'a'; cur=ch[cur][c];
            for(int f=cur;f!=rot;f=fail[f]) ans+=cnt[f], cnt[f]=0;
        }
        return ans;
    }
    
    int n,T;
    char str[SZ];
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            rot=e=1;
            memset(ch,0,sizeof(ch));
            memset(fail,0,sizeof(fail));
            memset(cnt,0,sizeof(cnt));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%s",str);
                insert(str);
            }
            bfail();
            scanf("%s",str);
            printf("%d
    ",match(str));
        }
    }

    manacher

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define SZ 666666
    int p[SZ];
    char str[SZ];
    void manacher()
    {
        int ml=0,id;
        for(int i=0;str[i];i++)
        {
            if(ml>i) p[i]=min(p[2*id-i],p[id]+id-i);
            else p[i]=1;
            while(i>=p[i]&&str[i+p[i]]==str[i-p[i]]) ++p[i];
            if(p[i]+i>ml) ml=p[i]+i, id=i;
        }
    }
    char s[SZ];
    void init()
    {
        str[0]='$'; int n=1;
        for(int i=0;s[i];i++) str[n++]=s[i], str[n++]='$';
        str[n]=0;
    }
    int main()
    {
        while(gets(s))
        {
            if(!s[0]) continue;
            init(); manacher();
            int ans=0;
            for(int i=0;str[i];i++) ans=max(ans,p[i]);
            printf("%d
    ",ans-1);
        }
        return 0;
    }

    回文树

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <math.h>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    struct PTree
    {
    #define SZ 666666
    int ch[SZ][26],len[SZ],fail[SZ],cnt[SZ],s[SZ],cl,an,lst;
    int addn(int l) {len[an]=l; return an++;}
    PTree()
    {
        cl=an=lst=0;
        memset(ch,0,sizeof(ch));
        addn(0); addn(-1);
        fail[0]=1; s[0]=-233;
    }
    int gfail(int x,int l)
    {
        while(s[l-len[x]-1]!=s[l]) x=fail[x];
        return x;
    }
    void add(int c)
    {
        s[++cl]=c;
        int cp=gfail(lst,cl);
        if(!ch[cp][c])
        {
            int nn=addn(len[cp]+2);
            fail[nn]=ch[gfail(fail[cp],cl)][c];
            ch[cp][c]=nn;
        }
        cnt[lst=ch[cp][c]]++;
    }
    void getcnt()
    {
        for(int i=an-1;i>=2;i--) cnt[fail[i]]+=cnt[i];
    }
    }pt;
    
    char s[SZ];
    int main()
    {
        scanf("%s",s);
        for(int i=0;s[i];i++) pt.add(s[i]-'a');
        pt.getcnt();
        long long ans=0;
        for(int i=2;i<=pt.an;i++) ans=max(ans,pt.len[i]*(long long)pt.cnt[i]);
        printf("%lld
    ",ans);
    }

    本来这篇文章是想放一些字符串题目,在前面整一下模板...没想到整了这么长...就下一篇文章放题目好了。

  • 相关阅读:
    Mysql8.0中caching_sha2_password报错解决
    Centos7 安装mysql-8.0.18(rpm)
    如何有效的清理yum缓存
    虚拟机安装后配置IP地址
    正确计算linux系统内存使用率
    Linux 怎样更改locale语言设置
    linux把EDT时间修改为CST格式
    开放接口的安全验证方案(AES+RSA)
    Linux下JDK中文字体乱码
    服务器http请求https服务时报错解决方案
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/5589289.html
Copyright © 2020-2023  润新知