zoukankan      html  css  js  c++  java
  • hdu_3518_Boring counting(后缀数组)

    题目链接:hdu_3518_Boring counting

    题意:

    给你一个字符串,让你找不重叠且出现大于1次以上的字串个数

    题解:

    后缀数组height数组的应用,我们枚举字串的长度,然后将height数组分段,符合条件就ans++

    为什么要这样做,因为height数组存的是相邻排名后缀的最大前缀数,如果height的值大于等于我们枚举的长度len,

    那么有可能这一段存在有两个以上的该长度的字串,然后我们统计这个段的开头长度l和结束长度r,如果r-l>=len,说明这段必有

    大于一个以上的该长度的相同子串,因为我们每次都是枚举len,按len分的段,所以不会重复。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;++i)
     3 using namespace std;
     4 
     5 namespace suffixarray{
     6     #define FN(n) for(int i=0;i<n;i++)
     7     const int N =1E3+7;
     8     int rnk[N],sa[N],height[N],c[N];char s[N];
     9     void getsa(int n,int m,int *x=rnk,int *y=height){
    10         FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
    11         for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
    12         for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
    13             for(int i=n-k;i<n;i++)y[p++]=i;
    14             FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
    15             FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
    16             for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
    17             swap(x,y),p=1,x[sa[0]]=0;
    18             for(int i=1;i<n;i++)
    19             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
    20         }
    21         FN(n)rnk[sa[i]]=i;
    22         for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
    23         for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
    24     }
    25 }
    26 
    27 inline void upd(int &a,int b){if(a>b)a=b;}
    28 inline void upu(int &a,int b){if(a<b)a=b;}
    29 
    30 using namespace suffixarray;
    31 int main(){
    32     while(~scanf("%s",s))
    33     {
    34         if(s[0]=='#')break;
    35         int len=strlen(s),ans=0;
    36         getsa(len+1,128);
    37         F(i,1,len)
    38         {
    39             int l=len+1,r=0;
    40             F(j,1,len)
    41             {
    42                 if(height[j]>=i)upd(l,sa[j]),upu(r,sa[j]);
    43                 else
    44                 {
    45                     if(r-l>=i)ans++;
    46                     l=r=sa[j];
    47                 }
    48             }
    49             if(r-l>=i)ans++;
    50         }
    51         printf("%d
    ",ans);
    52     }
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    20170417列表的count计数、index、reverse、sort函数
    (一)grpc-创建一个简单的grpc 客户端和服务器
    通用装饰器
    Git学习(一):Git介绍、仓库和分支等基本概念解释
    APP测试
    接口测试用例设计
    笔记整理
    接口测试
    gzip -压缩与解压缩
    declare 命令 -声明shell 变量
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5744647.html
Copyright © 2011-2022 走看看