zoukankan      html  css  js  c++  java
  • 后缀自动机

    P3804 【模板】后缀自动机 (SAM)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e6+100;
    typedef long long ll;
    
    char s[N];
    int ch[N*2][26],len[N*2],fa[N*2];
    int last=1,tot=1;
    int cnt[N],c[N];
    void add(int c) {
        int p=last,np=last=++tot;
        len[np]=len[p]+1; cnt[np]=1;
        for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
        if(!p) fa[np]=1;
        else {
            int q=ch[p][c];
            if(len[q]==len[p]+1) fa[np]=q;
            else {
                int nq=++tot;len[nq]=len[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];fa[q]=fa[np]=nq;
                for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            }
        }
    }
    int a[N];
    ll ans;
    int main() {
        cin>>s+1;
        for(int i=1;s[i];i++) add(s[i]-'a');
        for(int i=1;i<=tot;i++) c[len[i]]++;
        for(int i=1;i<=tot;i++) c[i]+=c[i-1];
        for(int i=1;i<=tot;i++) a[c[len[i]]--]=i;
        for(int i=tot;i;i--) {
            int p=a[i];
            cnt[fa[p]]+=cnt[p];
            if(cnt[p]>1) ans=max(ans,1ll*cnt[p]*len[p]);
        }
        cout<<ans;
    }
    View Code

    P3181 [HAOI2016]找相同字符

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e6+100;
    typedef long long ll;
    
    char s[N];
    int ch[N*2][27],len[N*2],fa[N*2];
    int last=1,tot=1;
    int cnt[N][2],c[N];
    void add(int c,int f) {
        int p=last,np=last=++tot;
        len[np]=len[p]+1; cnt[np][f]=1;
        for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
        if(!p) fa[np]=1;
        else {
            int q=ch[p][c];
            if(len[q]==len[p]+1) fa[np]=q;
            else {
                int nq=++tot;len[nq]=len[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];fa[q]=fa[np]=nq;
                for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            }
        }
    }
    int a[N],le;
    ll ans;
    int main() {
        cin>>s+1;le=strlen(s+1);
        for(int i=1;i<=le;i++) add(s[i]-'a',0);
        add(26,0);
        cin>>s+1;le=strlen(s+1);
        for(int i=1;i<=le;i++) add(s[i]-'a',1);
        for(int i=1;i<=tot;i++) c[len[i]]++;
        for(int i=1;i<=tot;i++) c[i]+=c[i-1];
        for(int i=1;i<=tot;i++) a[c[len[i]]--]=i;
        for(int i=tot;i;i--) {
            int p=a[i];
            cnt[fa[p]][0]+=cnt[p][0];
            cnt[fa[p]][1]+=cnt[p][1];
        }
        for(int i=1;i<=tot;i++) ans+=1ll*cnt[i][0]*cnt[i][1]*(len[i]-len[fa[i]]);
        cout<<ans;
    }
    View Code

    P3975 [TJOI2015]弦论

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e6+100;
    typedef long long ll;
    
    char s[N];
    int ch[N*2][27],len[N*2],fa[N*2];
    int last=1,tot=1;
    int cnt[N],c[N];
    void add(int c) {
        int p=last,np=last=++tot;
        len[np]=len[p]+1; cnt[np]=1;
        for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
        if(!p) fa[np]=1;
        else {
            int q=ch[p][c];
            if(len[q]==len[p]+1) fa[np]=q;
            else {
                int nq=++tot;len[nq]=len[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];fa[q]=fa[np]=nq;
                for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            }
        }
    }
    int a[N],le,t,k,siz[N];
    void getans(int x,int k,string &ans) {
        if(k<=cnt[x]) {cout<<ans;return;}
        k-=cnt[x];
        for(int i=0;i<26;i++) if(ch[x][i]) {
            int v=ch[x][i];
            if(k<=siz[v]) {getans(v,k,ans+=char(i+'a'));return ;}
            k-=siz[v];
        }
    }
    
    int main() {
        cin>>s+1;
        int L=strlen(s+1);
        cin>>t>>k;
        for(int i=1;i<=L;i++) add(s[i]-'a');
        for(int i=1;i<=tot;i++) c[len[i]]++;
        for(int i=1;i<=tot;i++) c[i]+=c[i-1];
        for(int i=1;i<=tot;i++) a[c[len[i]]--]=i;
    
        for(int i=tot;i;i--)
            if(t) cnt[fa[a[i]]]+=cnt[a[i]];
            else cnt[a[i]]=1;
        cnt[1]=0;
        for(int i=tot;i;i--) {
            siz[a[i]]=cnt[a[i]];
            for(int j=0;j<26;j++) if(ch[a[i]][j])
                siz[a[i]]+=siz[ch[a[i]][j]];
        }
        if(k>siz[1]) return printf("-1"),0;
        string ans;
        getans(1,k,ans);
    }
    View Code

    P1368 工艺

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+100;
    typedef long long ll;
    
    char s[N];
    map<int,int>ch[N*2];int len[N*2],fa[N*2];
    int last=1,tot=1;
    
    void add(int c) {
        int p=last,np=last=++tot;
        len[np]=len[p]+1;
        for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
        if(!p) fa[np]=1;
        else {
            int q=ch[p][c];
            if(len[q]==len[p]+1) fa[np]=q;
            else {
                int nq=++tot;len[nq]=len[p]+1;
                ch[nq]=ch[q];
                //memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];fa[q]=fa[np]=nq;
                for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            }
        }
    }
    int n,a[N];
    int main() {
        cin>>n;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int j=1;j<=2;j++)
        for(int i=1;i<=n;i++) add(a[i]);
        int pos=1;
        while(n--) {
            auto v=ch[pos].begin();
            printf("%d ",(*v).first);
            pos=(*v).second;
        }
    }
    View Code
  • 相关阅读:
    (WPF)实现DataGrid中当某一列的值显示为密码样式
    利用双栈实现撤销与恢复逻辑
    WPF 中ContextMenu 在mvvm模式中的绑定问题
    WPF使用StringFormat绑定
    不注册调用COM组件
    再谈WPF绑定
    WPF的动态资源和静态资源
    MDI窗体(Winform)
    mysql 查询json字符串中符合条件的值
    phpstudy 导入sql到phpmyadmin中sql过大导致失败解决办法
  • 原文地址:https://www.cnblogs.com/bxd123/p/12274269.html
Copyright © 2011-2022 走看看