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

    后缀自动机还是只会打板子,已经知道它是个什么东西了,但还是和它的构造联系不起来。。先背板子吧。

    后缀自动机有一个很好的特性就是可以涵盖所有不重复的子串,我们利用这一点在它上面dp就行了;

    代码参考:http://blog.csdn.net/fuxey/article/details/51050474

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int mod=2012,maxn=400010;
    char ss[maxn],s[maxn];
    int tt[maxn],last,cur=1,cnt=1,n,len,sum[maxn],ch[maxn][10],fa[maxn],dis[maxn];
    int c[maxn],q[maxn];
    void add(int c,int id){
        last=cur;cur=++cnt;
        int p=last;dis[cur]=id;
        for(;p&&!ch[p][c];p=fa[p])ch[p][c]=cur;
        if(!p)fa[cur]=1;
        else{
            int q=ch[p][c];
            if(dis[q]==dis[p]+1)fa[cur]=q;
            else{
                int nt=++cnt;dis[nt]=dis[p]+1;
                memcpy(ch[nt],ch[q],sizeof(ch[0]));
                fa[nt]=fa[q];fa[q]=fa[cur]=nt;
                for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nt;
            }
        }
    }
    void rsort(){
        memset(c,0,sizeof(c));
        for(int i=1;i<=cnt;++i)c[dis[i]]++;
        for(int i=1;i<=cnt;++i)c[i]+=c[i-1];
        for(int i=1;i<=cnt;++i)q[c[dis[i]]--]=i;
    }
    int main(){
        while(cin>>n){
            cnt=1;memset(fa,0,sizeof(fa));
            memset(ch,0,sizeof(ch));
            for(int i=1;i<=n;++i){
                scanf("%s",ss+1);
                cur=1;len=strlen(ss+1);
                for(int j=1;j<=len;++j)add(ss[j]-'0',j);
            }
            rsort();//先排一遍序保证计算顺序没有问题,保证一个点在更新别的点之前已经被所有能到它的点更新过;
            memset(sum,0,sizeof(sum));memset(tt,0,sizeof(tt));
            sum[1]=0;tt[1]=1;
            for(int i=1,j;i<=cnt;++i){
                j=q[i];
                for(int k=0,t;k<10;++k){
                    if(j==1&&(!k))continue;
                    t=ch[j][k];
                    (sum[t]+=tt[j]*k+sum[j]*10)%=mod;
                    (tt[t]+=tt[j])%=mod;
                    //cout<<sum[t]<<' '<<tt[t]<<endl;
                }
            }
            int ans=0;
            for(int i=1;i<=cnt;++i){(ans+=sum[i])%=mod;}
            printf("%d
    ",ans);
        }
        //system("pause");
        return 0;
    }
    /*
    5
    101
    123
    09
    000
    1234567890
    */
  • 相关阅读:
    (IDEA) VCS-->Import Into Version Control没有Share Project(Subversion)这个选项。
    Maven学习笔记(二)—— 整合SSH框架
    Maven学习笔记(一)—— Maven基础
    使用IDEA完成maven整合SSH框架时抛出Hibernate : Mapping (RESOURCE) not found
    mysql性能的检查和优化方法
    每个php程序员都应该知道的15个最佳PHP库
    linux oracle 11g 漏洞补丁升级
    linux 启动MongoDB
    linux 7 查看oracle 11g版本号
    linux 清除缓存命令
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8387258.html
Copyright © 2011-2022 走看看