字符串题目

 回文自动机模板

#include<bits/stdc++.h>
using namespace std;
struct PAM{
    #define ll long long
    #define LL long long
    static const int maxn=3e5+10;
    static const int num=27;
    char ss[maxn];  int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    //LL ans;
    void inint(){
        c=0;
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c]='a'+x;  c++;
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot; //ans++;
        }
        cnt[last=ch[p][x]]++;
    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0;
    }
}pam;
const int maxn=1e5+10;
char ss[maxn];
int main(){

}
回文自动机

回文自动机   本质不同回文串个数   tot-1;

#include<bits/stdc++.h>
#define ll long long
#define LL long long
using namespace std;
const int maxn=2e5+10;
const int num=26;
char ss[maxn];
int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
struct PAM{
    int last,tot;
    ll ans;
    void inint(){
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot;
        }
        cnt[last=ch[p][x]]++;
    }
    void count(){  //  bu zhi bu tong hui wen ge shu
        for(int i=tot;i>=0;i--){
            cnt[fail[i]]+=cnt[i];
            cnt[fail[i]]%=51123987;
        }
    }
    ll count_tot(){
        ll w=0; count();
        for(int i=2;i<=tot;i++) w+=cnt[i];
        return w;
    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0;
    }
}pam;
int main(){
    //int x; scanf("%d",&x);
    scanf("%s",ss);
    int l=strlen(ss); pam.inint();
    for(int i=0;i<l;i++) {
        pam.add(ss[i]-'a',i);
        if(i!=0) printf(" ");
        printf("%d",pam.tot-1);
    }
}
View Code

 回文自动机  字符串l-r  区间本质不同回文串个数    

#include<bits/stdc++.h>
#define ll long long
#define LL long long
using namespace std;
const int maxn=1010;
struct PAM{
    static const int maxn=1e3+10;
    static const int num=26;
    char ss[maxn];  int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    ll ans;
    void inint(){
        last=0;  tot=0; c=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c++]=x+'a';
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot;
        }
        cnt[last=ch[p][x]]++;
    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0; c=0;
    }
}pam;
char ss[maxn];
int a[maxn][maxn];
int main(){
    int T; scanf("%d",&T);
    while(T--){
        scanf("%s",ss);
        int q; scanf("%d",&q);
        int n=strlen(ss);
        for(int i=0;i<n;i++){
            pam.clear();
            pam.inint();
            for(int j=i;j<n;j++){
                pam.add(ss[j]-'a',j-i);
                a[i][j]=pam.tot-1;
            }
        }
        while(q--){
            int l,r; scanf("%d %d",&l,&r);
            printf("%d\n",a[l-1][r-1]);
        }
    }
}
Vbuiew Code

 回文自动机   回文串权值问题

#include<bits/stdc++.h>
#define ll long long
#define LL long long
using namespace std;
const int maxn=1010000;
struct PAM{
    static const int maxn=3e5+10;
    static const int num=26;
    char ss[maxn];  int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    ll ans=0;
    void inint(){
        last=0;  tot=0; c=0; ans=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c++]=x+'a';
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot;
        }
        cnt[last=ch[p][x]]++;
    }
    void  dfs(int x){
        for(int i=0;i<num;i++){
            if(ch[x][i]){
                int w=ch[x][i];
                //cout<<w<<" "<<cnt[w]<<" "<<len[w]<<endl;
                ans=max(1ll*cnt[w]*len[w],ans);
                dfs(w);
            }
        }

    }
    ll slove(){
        for(int i=tot;i>=0;i--) cnt[fail[i]]+=cnt[i];
        dfs(1);  dfs(0);
        return ans;
    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0; c=0;
    }
}pam;
char ss[maxn];
int a[maxn][maxn];
int main(){
    scanf("%s",ss);
    pam.inint();
    int n=strlen(ss);
    for(int i=0;i<n;i++){
        pam.add(ss[i]-'a',i);
    }
    printf("%lld\n",pam.slove());
}
View Code

 hdu 5394  回文自动机上删点 加点操作  回文自动机上记忆化搜索

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<vector>
#include<stdio.h>
#include<math.h>
using namespace std;
struct PAM{
    #define ll long long
    #define LL long long
    static const int maxn=2e6+10;
    static const int num=27;
    char ss[maxn];
    int relast[maxn];
    int  retot[maxn];
    ll   sum[maxn];
    bool check[maxn];
    int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    void inint(){
        c=0;
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c]='a'+x;  c++;
        relast[pos]=last;//
        retot[pos]=tot;//
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            check[pos]=1;//
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot;
        }
        cnt[last=ch[p][x]]++;

    }
    void re(int x,int pos){
        c--;
        last=relast[pos];
        tot=retot[pos];
        int p=get_fail(last,pos);
        if(check[pos]==1){
            check[pos]=0;
            len[++tot]=0;
            fail[tot]=0;
            ch[p][x]=0;
            sum[tot]=0;
        }
        cnt[last=ch[p][x]]--;
        last=relast[pos]; tot=retot[pos];
        relast[pos]=0; retot[pos]=0;
    }
    ll dfs(int x){

        if(x==0 || x==1) return 0;
        if(sum[x]!=0) return sum[x];
        return  sum[x]=dfs(fail[x])+len[x];
    }
    ll work(){
       return dfs(last);
    }

}pam;
#define ll long long
const int maxn=2e6+10;
//char ss[maxn];
ll ans=0;
vector<pair<int,char> > vs[maxn];
void dfs(int x,int tot){
    for(int i=0;i<vs[x].size();i++){

        pam.add(vs[x][i].second,tot);
        ans+=pam.work();

        dfs(vs[x][i].first,tot+1);
        pam.re(vs[x][i].second,tot);
    }
}
struct FastIO {
    static const int S = 4e6;
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) {}
    inline int xchar() {
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len)
            pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len) exit(0);
        return buf[pos++];
    }
    inline int xuint() {
        int c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x;
    }
    inline int xint()
    {
        int s = 1, c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        if (c == '-') s = -1, c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x * s;
    }
    inline void xstring(char *s)
    {
        int c = xchar();
        while (c <= 32) c = xchar();
        for (; c > 32; c = xchar()) * s++ = c;
        *s = 0;
    }
    inline void wchar(int x)
    {
        if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
        wbuf[wpos++] = x;
    }
    inline void wint(int x)
    {
        if (x < 0) wchar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n--) wchar(s[n]);
        wchar('\n');
    }
    inline void wstring(const char *s)
    {
        while (*s) wchar(*s++);
    }
    ~FastIO()
    {
        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
} io;
int main(){
    int T;
     T=io.xint();
    //cin>>T;
    while(T--){
        pam.inint();
        ans=0;
        int n;
        n=io.xint();
        //cin>>n;
        for(int i=1;i<=n;i++){
            char x; int y;
            x=io.xchar();
            y=io.xint();
            //cin>>x>>y;
            vs[y].push_back({i,x});
        }
        dfs(0,0);
        printf("%lld\n",ans);
        for(int i=0;i<=n;i++) vs[i].clear();
       // pam.clear();
    }
}
View Code

 洛谷  最长双回文串

#include<bits/stdc++.h>
using namespace std;
struct PAM{
    #define ll long long
    #define LL long long
    static const int maxn=3e5+10;
    static const int num=27;
    char ss[maxn];  int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    LL ans;
    void inint(){
        c=0;
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c]='a'+x;  c++;
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot; ans++;
        }
        cnt[last=ch[p][x]]++;
    }
    int work(){
        return len[last];
    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0;
    }
}pam;
const int maxn=2e5+10;
char ss[maxn];
int ans[maxn];
int main(){
    scanf("%s",ss);  int l=strlen(ss);
    pam.inint();
    for(int i=0;i<l;i++){
        pam.add(ss[i],i);
        ans[i]+=pam.work();

    }
    pam.clear();
    pam.inint();
    for(int i=l-1;i>=0;i--){
        pam.add(ss[i],l-1-i);
        if(i-1>=0) ans[i-1]+=pam.work();
    }
    int x=0;
    for(int i=1;i<l-1;i++){
        x=max(ans[i],x);
    }
    printf("%d\n",x);

}
View Code

 洛谷  拉拉队排练

#include<bits/stdc++.h>
using namespace std;
int numm[2000005];
struct PAM{
    #define ll long long
    #define LL long long
    static const int maxn=2e6+10;
    static const int num=27;
    char ss[maxn];  int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    LL ans;
    void inint(){
        c=0;
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c]='a'+x;  c++;
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot; ans++;
        }
        cnt[last=ch[p][x]]++;
    }
    void count(){
        for(int i=tot;i>=2;i--){
            cnt[fail[i]]+=cnt[i];
            if(len[i]%2==1){
                numm[len[i]]+=cnt[i];
            }
        }


    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0;
    }
}pam;
const int maxn=2e6+10;
const int mod=19930726;
#define ll long long
char ss[maxn];
int quick(int x,int n){
    int ans=1;
    while(n){
        if(n&1) ans=1ll*ans*x%mod;
        x=1ll*x*x%mod;
        n=n/2;
    }
    return ans;

}
int main(){
    ll n,k; scanf("%lld %lld",&n,&k);
    scanf("%s",ss);
    pam.inint();
    for(int i=0;i<n;i++)pam.add(ss[i],i);
    pam.count();
    ll ans=1;
    ll w=0;
    for(int i=n;i>=1;i--){
            //cout<<numm[i]<<endl;
        if(i%2==1) w+=numm[i];
        if(i%2==1 && k){
            if(numm[i]<=k){
                ans=1ll*ans*quick(i,numm[i])%mod;
                k-=numm[i];
            }
            else {
                ans=1ll*ans*quick(i,k)%mod;
                k=0;
            }
        }
    }
    if(w<k) printf("-1\n");
    else printf("%lld\n",ans);
}
View Code

 hdu 5157

#include<bits/stdc++.h>
using namespace std;
struct PAM{
    #define ll long long
    #define LL long long
    static const int maxn=2e5+10;
    static const int num=27;
    char ss[maxn];  int c=0;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    int sum[maxn];
    //LL ans;
    void inint(){
        c=0;
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        ss[c]='a'+x;  c++;
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot; //ans++;
        }
        cnt[last=ch[p][x]]++;
    }
    int dfs(int x){
        if(x==0 || x==1) return 0;
        if(sum[x]!=0) return sum[x];
        return sum[x]=dfs(fail[x])+1;
    }
    int work(){ return dfs(last); }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0; sum[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=0;
    }
}pam;
#define ll long long
const int maxn=1e5+10;
char ss[maxn];
ll a[maxn];
ll b[maxn];
ll sumb[maxn];
int main(){
    while(scanf("%s",ss)!=EOF){
        int l=strlen(ss);
        pam.inint();
        for(int i=0;i<l;i++){
            pam.add(ss[i]-'a',i);
            a[i]=pam.work();
        }
        pam.clear();
        pam.inint();
        for(int i=l-1;i>=0;i--){
            pam.add(ss[i]-'a',l-1-i);
            b[i]=pam.work();
        }
        for(int i=l-1;i>=0;i--){
            sumb[i]=sumb[i+1]+b[i];
        }
        ll ans=0;
        for(int i=0;i<l;i++){
            ans+=1ll*a[i]*sumb[i+1];
        }
        printf("%lld\n",ans);
        for(int i=0;i<=l;i++) a[i]=b[i]=sumb[i]=0;
        pam.clear();
    }
}
View Code

hdu  6599  回文自动机   哈希  回文串 (l-r)回文  (l-(l+r)/2)回文)

#include<bits/stdc++.h>
#define ll long long
#define LL long long
using namespace std;
const int maxn=3e5+10;
const int mod=1e9+7;
const int h1=222333;
char ss[maxn];
int a[maxn];
int ha[maxn];
int hb[maxn];
int hh[maxn];
struct PAM{
    #define ll long long
    #define LL long long
    static const int maxn=3e5+10;
    static const int num=27;
    int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num];
    int last,tot;
    LL ans;
    void inint(){
        last=0;  tot=0;
        fail[0]=fail[1]=1;
        len[0]=0; len[1]=-1; tot++;
    }
    int get_fail(int p,int pos){
         while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p];
         return p;
    }
    void add(int x,int pos){
        int p=get_fail(last,pos);
        if(!ch[p][x]){
            len[++tot]=len[p]+2;
            fail[tot]=ch[get_fail(fail[p],pos)][x];
            ch[p][x]=tot; ans++;
        }
        cnt[last=ch[p][x]]++;
    }
    void count(){  //  bu zhi bu tong hui wen ge shu
        for(int i=tot;i>=0;i--){
            cnt[fail[i]]+=cnt[i];
        }
    }
    void dfs(int x,int pos){
        for(int i=0;i<num;i++){
            if(ch[x][i]){
                if(pos==0) ha[pos]=(1ll*i)%mod;
                else       ha[pos]=(1ll*ha[pos-1]*h1+i)%mod;
                if(pos==0) hb[pos]=(1ll*i*hh[pos])%mod;
                else       hb[pos]=(1ll*i*hh[pos]+hb[pos-1])%mod;
                int k=ch[x][i];
                if(ha[pos]==hb[pos]){
                    a[len[k]]+=cnt[k];
                }
                dfs(k,pos+1);

            }
        }
    }
    void work(){
        dfs(0,0);
        dfs(1,0);
    }
    void clear(){
        for(int i=0;i<=tot;i++){
            fail[i]=0; len[i]=0; cnt[i]=0;
            for(int j=0;j<num;j++) ch[i][j]=0;
        }
        last=tot=ans=0;
    }
}pam;
int main(){
    hh[0]=1;  for(int i=1;i<maxn;i++) hh[i]=1ll*hh[i-1]*h1%mod;
    while(~scanf("%s",ss)){
        int l=strlen(ss); pam.inint();  //cout<<l<<endl;
        for(int i=0;i<l;i++)  pam.add(ss[i]-'a',i);
        pam.count();  pam.work();
        for(int i=1;i<=l;i++){
            if(i!=1) printf(" ");
            printf("%d",a[i]); a[i]=0;
        }printf("\n");
        pam.clear();
    }
}
View Code

 

 

 

后缀自动机

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct SAM    // /* https://www.cnblogs.com/weeping/p/7516063.html */
{
    static const int MAXN = 50000<<1;//大小为字符串长度两倍
    static const int LetterSize = 300;
    int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
    int num[MAXN];
    void init( void)
    {
        last = tot = 1;  len[1] = 0;
        memset( ch[1], 0, sizeof ch[1]);
    }
    void add( int x) {
        int p = last, np = last = ++tot;  num[tot]=1;
        len[np] = len[p] + 1;//cnt[last] = 1;
        memset( ch[np], 0, sizeof ch[np]);
        while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
        if( p == 0)  fa[np] = 1;
        else
        {
            int q = ch[p][x];
            if( len[q] == len[p] + 1)  fa[np] = q;
            else
            {
                int nq = ++tot;
                memcpy( ch[nq], ch[q], sizeof ch[q]);
                len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
                while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
            }
        }
    }
    void use(){
        ll ans=0;
        for(int i=2;i<=tot;i++) { ans+=len[i]-len[fa[i]]; }
        printf("%lld\n",ans);
    }
}sam;
const int maxn=1e6+10;
char ss[maxn];
int main(){
    int T; scanf("%d",&T);
    while(T--){
        scanf("%s",ss); int l=strlen(ss); sam.init();
        for(int i=0;i<l;i++)  sam.add(ss[i]-'a');
        sam.use();
    }
}
View Code

 本质不同字符串个数(模板题)New Distinct Substrings SPOJ - SUBST1 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct SAM{
    static const int MAXN = 50000<<1;//大小为字符串长度两倍
    static const int LetterSize = 300;
    int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
    int num[MAXN];
    void init( void)
    {
        last = tot = 1;  len[1] = 0;
        memset( ch[1], 0, sizeof ch[1]);
    }
    void add( int x) {
        int p = last, np = last = ++tot;  num[tot]=1;
        len[np] = len[p] + 1;//cnt[last] = 1;
        memset( ch[np], 0, sizeof ch[np]);
        while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
        if( p == 0)  fa[np] = 1;
        else
        {
            int q = ch[p][x];
            if( len[q] == len[p] + 1)  fa[np] = q;
            else
            {
                int nq = ++tot;
                memcpy( ch[nq], ch[q], sizeof ch[q]);
                len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
                while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
            }
        }
    }
    void use(){
        ll ans=0;
        for(int i=2;i<=tot;i++) { ans+=len[i]-len[fa[i]]; }
        printf("%lld\n",ans);
    }
}sam;
const int maxn=1e6+10;
char ss[maxn];
int main(){
    int T; scanf("%d",&T);
    while(T--){
        scanf("%s",ss); int l=strlen(ss); sam.init();
        for(int i=0;i<l;i++)  sam.add(ss[i]-'a');
        sam.use();
    }
}
View Code

 两字符串的最长相同字串

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct SAM{
    static const int MAXN = 250010<<1;//大小为字符串长度两倍
    static const int LetterSize = 300;
    int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
    int num[MAXN];
    void init( void){
        last = tot = 1;  len[1] = 0; len[0]=0;
        memset( ch[1], 0, sizeof ch[1]);
    }
    void add( int x) {
        int p = last, np = last = ++tot;  num[tot]=1;
        len[np] = len[p] + 1;
        memset(ch[np],0,sizeof ch[np]);
        while(p&&!ch[p][x]) ch[p][x] = np, p = fa[p];
        if( p == 0)  fa[np] = 1;
        else{
            int q = ch[p][x];
            if( len[q] == len[p] + 1)  fa[np] = q;
            else{
                int nq = ++tot;
                memcpy( ch[nq], ch[q], sizeof ch[q]);
                len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
                while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
            }
        }
    }
}sam;
const int maxn=1e6+10;
char ss[maxn];
char tt[maxn];
int main(){
    scanf("%s",ss); int l=strlen(ss); sam.init();
    for(int i=0;i<l;i++)  sam.add(ss[i]-'a');
    scanf("%s",tt); int r=strlen(tt);
    int ans=0;
    int p=1;
    int d=0;
    for(int i=0;i<r;i++){
       if(sam.ch[p][tt[i]-'a']){
            p=sam.ch[p][tt[i]-'a'];
            d++;
       }
       else {
            while(sam.ch[p][tt[i]-'a']==0 && p!=1){
                p=sam.fa[p];
                d=sam.len[p];
            }
            if(sam.ch[p][tt[i]-'a'])  { p=sam.ch[p][tt[i]-'a']; d++;}
       }
       //cout<<d<<endl;
       ans=max(ans,d);
    }
    printf("%d\n",ans);
}
View Code

 hdu 6583   后缀自动机 + dp    http://acm.hdu.edu.cn/showproblem.php?pid=6583

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
#define ll long long
#define LL long long
using namespace std;
struct SAM
{
    static const int MAXN = 200010<<1;//大小为字符串长度两倍
    static const int LetterSize = 26;
    int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
    int num[MAXN];
    void init( void)
    {
        last = tot = 1;  len[1] = 0; fa[1]=0;
        memset( ch, 0, sizeof(ch));
        memset( fa,0,sizeof(fa));
        memset( len,0,sizeof(len));
    }
    void add( int x) {
        int p = last, np = last = ++tot;  num[tot]=1;
        len[np] = len[p] + 1;
        memset( ch[np], 0, sizeof ch[np]);
        while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
        if( p == 0)  fa[np] = 1;
        else
        {
            int q = ch[p][x];
            if( len[q] == len[p] + 1)  fa[np] = q;
            else
            {
                int nq = ++tot;
                memcpy( ch[nq], ch[q], sizeof ch[q]);
                len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
                while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
            }
        }
    }
}sam;
const int maxn=2e5+10;
char ss[maxn];
ll dp[maxn];
int main(){
    while(~scanf("%s",ss)){
        int p,q; scanf("%d %d",&p,&q);
        int l=strlen(ss);
        sam.init();
        int now=1;
        int j=0;
        for(int i=0;i<l;i++) dp[i]=1e18;
        for(int i=0;i<l;i++){
            if(i==0)   dp[i]=p;
            else       dp[i]=min(dp[i],dp[i-1]+p);
            int x=ss[i]-'a';
            while(  (!sam.ch[now][x] || i-j+1>=j+1) &&j<=i    ){
                  sam.add(ss[j++]-'a');
                  while(now && sam.len[sam.fa[now]]>=i-j) now=sam.fa[now];
                  if(!now) now=1;
            }
            now=sam.ch[now][x];
            while(now && sam.len[sam.fa[now]]>=i-j+1) now=sam.fa[now];
            if(!now) now=1;
            if(i>=j){
                dp[i]=min(dp[i],dp[j-1]+q);
            }
           // cout<<dp[i]<<"  "<<i<<"   "<<j<<endl;
        }
        printf("%lld\n",dp[l-1]);
    }
}
View Code

 

转载于:https://www.cnblogs.com/Andromeda-Galaxy/p/11517152.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值