• spoj 8222 Substrings(后缀自动机+DP)


    【题目链接】

      http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28005  

    【题意】

        给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值。求F(1)..F(Length(S))

    【思路】

        建立一个SAM。

      对于SAM的一个结点u所代表的串,它的长度为|min(u),max(u)|,出现次数为|right(s)|,出现次数可以通过fa边将max并到一块得到。

      max(fa)=min(u)-1

      这只考虑了结点的最长串,对于介于max(fa)与max(u)长度之间的串我们还需要按长度递推一遍,f[i]=max{ f[i+1],f[i] },这样保证长度i得到了至少应得到的值。

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 const int N = 5*1e5+10;
     7 
     8 char s[N];
     9 int S,sz,last,ch[N][26],fa[N],l[N];
    10 
    11 void add(int x) {
    12     int c=s[x]-'a';
    13     int p=last,np=++sz; last=np;
    14     l[np]=x;
    15     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    16     if(!p) fa[np]=S;
    17     else {
    18         int q=ch[p][c];
    19         if(l[p]+1==l[q]) fa[np]=q;
    20         else {
    21             int nq=++sz; l[nq]=l[p]+1;
    22             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    23             fa[nq]=fa[q];
    24             fa[np]=fa[q]=nq;
    25             for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    26         }
    27     }
    28 }
    29 
    30 int b[N],r[N],f[N],t[N];
    31 
    32 int main() {
    33     scanf("%s",s+1);
    34     last=S=++sz;
    35     int len=strlen(s+1);
    36     for(int i=1;i<=len;i++) add(i);
    37     for(int i=1,p=S;i<=len;i++) {
    38         p=ch[p][s[i]-'a']; r[p]++;
    39     }
    40     for(int i=1;i<=sz;i++) b[l[i]]++;
    41     for(int i=1;i<=len;i++) b[i]+=b[i-1];
    42     for(int i=1;i<=sz;i++) t[b[l[i]]--]=i;                 //基排 
    43     for(int i=sz;i;i--) r[fa[t[i]]]+=r[t[i]];
    44     for(int i=1;i<=sz;i++) f[l[i]]=max(f[l[i]],r[i]);
    45     for(int i=len;i;i--) f[i]=max(f[i],f[i+1]);            //被包含的情况
    46     for(int i=1;i<=len;i++) printf("%d
    ",f[i]);
    47     return 0;
    48 }
  • 相关阅读:
    cmake的安装
    安装cmake过程g++: 错误:unrecognized command line option ‘-std=gnu++14’
    进程空间分配
    git 基本操作
    nm命令
    container_of 宏
    cmake
    fiddler修改Requests之前的数据和response 之后的数据
    Fiddler抓包请求前设置断点
    jmeter连接mysql数据库
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5197527.html
Copyright © 2020-2023  润新知