• [SPOJ705]不同的子串


    题目点这里

    我们发现这道题可以用后缀自动机做(不会的点这里

    我们发现后缀自动机每条路径代表一条子串,那么我们就DP:

    写法一

    #include<bits/stdc++.h>
    #define N 100071
    using namespace std;
    struct Node{
        int c[26],fa,val;
    }T[N];
    int tot=1,last=1,D[N],c[N],np,q,nq,len,id[N],ans;
    char ch[N];
    inline void Sam(int x){
        np=++tot; T[np].val=T[last].val+1;
        for (;last&&!T[last].c[x];last=T[last].fa) T[last].c[x]=np;
        if (!last) T[np].fa=1;
        else { q=T[last].c[x];
         if (T[q].val==T[last].val+1) T[np].fa=q;
         else  {
             nq=++tot; T[nq]=T[q];
             T[nq].val=T[last].val+1; T[np].fa=T[q].fa=nq;
             for (;last&&T[last].c[x]==q;last=T[last].fa) T[last].c[x]=nq;
         }
        } last=np; 
    }
    int main () {
        freopen("subst1.in","r",stdin);
        freopen("subst1.out","w",stdout);
        scanf("%s",ch+1);len=strlen(ch+1);
        for (int i=1;i<=len;i++)
         Sam(ch[i]-'A');
        for (int i=1;i<=tot;i++) c[T[i].val]++,D[i]=1;
        for (int i=1;i<=len;i++) c[i]+=c[i-1];
        for (int i=1;i<=tot;i++) id[c[T[i].val]--]=i;
        for (int i=tot;i;i--) 
         for (int j=0;j<26;j++)
          D[id[i]]+=D[T[id[i]].c[j]];
        printf("%d
    ",D[1]-1); 
    //    for (int i=tot;i;i--) ans+=T[i].val-T[T[i].fa].val;
    //    printf("%d
    ",ans);
        return 0;
    }

    我们可以把DP方程化简一下,得到写法二

    #include<bits/stdc++.h>
    #define N 100071
    using namespace std;
    struct Node{
        int c[26],fa,val;
    }T[N];
    int tot=1,last=1,D[N],c[N],np,q,nq,len,id[N],ans;
    char ch[N];
    inline void Sam(int x){
        np=++tot; T[np].val=T[last].val+1;
        for (;last&&!T[last].c[x];last=T[last].fa) T[last].c[x]=np;
        if (!last) T[np].fa=1;
        else { q=T[last].c[x];
         if (T[q].val==T[last].val+1) T[np].fa=q;
         else  {
             nq=++tot; T[nq]=T[q];
             T[nq].val=T[last].val+1; T[np].fa=T[q].fa=nq;
             for (;last&&T[last].c[x]==q;last=T[last].fa) T[last].c[x]=nq;
         }
        } last=np; 
    }
    int main () {
        freopen("subst1.in","r",stdin);
        freopen("subst1.out","w",stdout);
        scanf("%s",ch+1);len=strlen(ch+1);
        for (int i=1;i<=len;i++)
         Sam(ch[i]-'A');
    //    for (int i=1;i<=tot;i++) c[T[i].val]++,D[i]=1;
    //    for (int i=1;i<=len;i++) c[i]+=c[i-1];
    //    for (int i=1;i<=tot;i++) id[c[T[i].val]--]=i;
    //    for (int i=tot;i;i--) 
    //     for (int j=0;j<26;j++)
    //      D[id[i]]+=D[T[id[i]].c[j]];
    //    printf("%d
    ",D[1]-1); 
        for (int i=tot;i;i--) ans+=T[i].val-T[T[i].fa].val;
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    【原】Ubuntu13.04安装、卸载Gnome3.8
    【原】安装、卸载、查看软件时常用的命令
    【原】中文Ubuntu主目录下的文档文件夹改回英文
    【原】Ubuntu ATI/Intel双显卡 驱动安装
    【转】Hadoop vs Spark性能对比
    【译】Spark调优
    【转】Spark源码分析之-scheduler模块
    【转】Spark源码分析之-deploy模块
    【转】Spark源码分析之-Storage模块
    【转】弹性分布式数据集:一种基于内存的集群计算的容错性抽象方法
  • 原文地址:https://www.cnblogs.com/rrsb/p/8277736.html
Copyright © 2020-2023  润新知