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
  • 相关阅读:
    【JAVA SE基础篇】28.面向对象三大特征之多态
    【JAVA SE基础篇】27.面向对象三大特征之封装
    【JAVA SE基础篇】26.toString()方法和equlas()方法
    【JAVA SE基础篇】25.面向对象三大特征之继承
    【JAVA SE基础篇】24.包的机制和import详解
    ssh框架文件上传下载
    java格式化时间格式
    表单提交后打印后台传过来的数据
    使用ajaxfileupload.js实现文件上传
    JSTL跳出<c:forEach>循环
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5744647.html
Copyright © 2011-2022 走看看