zoukankan      html  css  js  c++  java
  • 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】

    题意

     给出一个字符串,要你找出所有长度的子串分别的最多出现次数。

    分析

      我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小。我们设f[len]为长度为len的子串的最多出现次数。我们对于自动机的每个状态都更新f,f[st[u].len]=max(f[st[u].len],cnt[u])。然后这样更新完以后,可以神奇的dp一下。f[len]=max(f[len],f[len+1]).想想为什么?

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 const int maxn=250000+100;
     8 char s[maxn];
     9 int n;
    10 struct state{
    11     int len,link;
    12     int ch[26];
    13 }st[maxn*2];
    14 int sz,last,cur,cnt[2*maxn],c[2*maxn],f[maxn];
    15 void init(){
    16     cur=last=0;
    17     sz=1;
    18     st[0].link=-1;
    19     st[0].len=0;
    20     memset(st[0].ch,-1,sizeof(st[0].ch));
    21 }
    22 void build_sam(int c){
    23     cur=sz++;
    24     st[cur].len=st[last].len+1;
    25     cnt[cur]=1;
    26     memset(st[cur].ch,-1,sizeof(st[cur].ch));
    27     int p;
    28     for(p=last;p!=-1&&st[p].ch[c]==-1;p=st[p].link)
    29         st[p].ch[c]=cur;
    30     if(p==-1)
    31         st[cur].link=0;
    32     else{
    33         int q=st[p].ch[c];
    34         if(st[q].len==st[p].len+1)
    35             st[cur].link=q;
    36         else{
    37             int clone=sz++;
    38             st[clone].len=st[p].len+1;
    39             st[clone].link=st[q].link;
    40             for(int i=0;i<26;i++)
    41                 st[clone].ch[i]=st[q].ch[i];
    42             for(;p!=-1&&st[p].ch[c]==q;p=st[p].link)
    43                 st[p].ch[c]=clone;
    44             st[q].link=st[cur].link=clone;
    45         }
    46     }
    47     last=cur;
    48 }
    49 int cmp(int a,int b){
    50     return st[a].len>st[b].len;
    51 }
    52 int main(){
    53     scanf("%s",s);
    54     n=strlen(s);
    55     init();
    56     for(int i=0;i<n;i++)
    57         build_sam(s[i]-'a');
    58     for(int i=0;i<sz;i++)
    59         c[i]=i;
    60     sort(c,c+sz,cmp);
    61 //    for(int i=0;i<sz;i++){
    62 //        printf("%d
    ",st[i].link);
    63 //    }
    64 //    printf("!!
    ");
    65 
    66     for(int i=0;i<sz;i++){
    67         int o=c[i];
    68         cnt[st[o].link]+=cnt[o];
    69     }
    70 //    for(int i=0;i<sz;i++)
    71 //        printf("%d ",cnt[i]);
    72 //    printf("
    ");
    73 
    74     for(int i=0;i<sz;i++)
    75         f[st[i].len]=max(f[st[i].len],cnt[i]);
    76     for(int i=n-1;i>=1;i--)
    77         f[i]=max(f[i],f[i+1]);
    78     for(int i=1;i<=n;i++){
    79         printf("%d
    ",f[i]);
    80     }
    81 return 0;
    82 }
    View Code
  • 相关阅读:
    人人学IoT 助学思维导图
    基于netty4.x开发时间服务器
    JAVA实现的截屏程序
    java获取硬盘ID以及MAC地址
    神经网络joone_engin模式识别示范,eclipse
    神经网络/人工智能 开源库
    双目测距
    OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
    一个java 开源神经网络引擎 joone
    用Java开源项目JOONE实现人工智能编程
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9882228.html
Copyright © 2011-2022 走看看