zoukankan      html  css  js  c++  java
  • hdu 3518(后缀数组)

    题意:容易理解...

    分析:这是我做的后缀数组第一题,做这个题只需要知道后缀数组中height数组代表的是什么就差不多会做了,height[i]表示排名第i的后缀与排名第i-1的后缀的最长公共前缀,然后我们可以枚举长度为k(1<=k<=len/2)的满足要求的子串个数,然后这个题的代码以后就作为求后缀数组的模板了!!

    代码实现:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    int ws1[1005],wv[1005],wa[1005],wb[1005];
    int rank[1005],height[1005],sa[1005];
    char str[1005];
    
    int cmp(int *r,int a,int b,int l)
    {
        return r[a]==r[b] && r[a+l]==r[b+l];
    }
    
    void da(char *r,int *sa,int n,int m)
    {
        int i,j,p,*x=wa,*y=wb,*t;
        for(i=0;i<m;i++)
            ws1[i]=0;
        for(i=0;i<n;i++)
            ws1[x[i]=r[i]]++;
        for(i=1;i<m;i++)
            ws1[i]+=ws1[i-1];
        for(i=n-1;i>=0;i--)
            sa[--ws1[x[i]]]=i;
        for(j=1,p=1;p<n;j*=2,m=p)
        {
            for(p=0,i=n-j;i<n;i++)
                y[p++]=i;
            for(i=0;i<n;i++)
                if(sa[i]>=j)
                    y[p++]=sa[i]-j;
            for(i=0;i<n;i++)
                wv[i]=x[y[i]];
            for(i=0;i<m;i++)
                ws1[i]=0;
            for(i=0;i<n;i++)
                ws1[wv[i]]++;
            for(i=1;i<m;i++)
                ws1[i]+=ws1[i-1];
            for(i=n-1;i>=0;i--)
                sa[--ws1[wv[i]]]=y[i];
            for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
                x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
        }
    }
    
    void calheight(char *r,int *sa,int n)
    {
        int i,j,k=0;
        for(i=1;i<=n;i++)
            rank[sa[i]]=i;
        for(i=0;i<n;height[rank[i++]]=k)
            for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++) ;
    }
    
    int main()
    {
        int len,i,j,l,r;
        __int64 res;
        while(scanf("%s",str)!=EOF&&str[0]!='#')
        {
            len=strlen(str);
            str[len]='0';
            da(str,sa,len+1,'z'+1);
            calheight(str,sa,len);
            res=0;
            for(i=1;i<=len/2;i++)
            {
                l=len+1;
                r=-1;
                for(j=2;j<=len;j++)
                {
                    if(height[j]>=i)
                    {
                        if(sa[j-1]>r)
                            r=sa[j-1];
                        if(sa[j-1]<l)
                            l=sa[j-1];
                        if(sa[j]>r)
                            r=sa[j];
                        if(sa[j]<l)
                            l=sa[j];
                    }
                    else
                    {
                        if(r-l>=i)
                            res++;
                        r=-1;
                        l=len+1;
                    }
                }
                if(r-l>=i)
                    res++;
            }
            printf("%I64d
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    VB.NET中lambda的写法
    C#中DllImport用法和路径问题
    SQL*Loader 和 Data Pump
    批处理-函数定义及应用01
    Office 2010 KMS激活原理和案例分享
    Hyper-V架构与VMware ESXi的差异
    Tomcat免安装配置2
    Tomcat免安装配置
    域名解析过程
    内部类访问的局部变量必须加final
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3241664.html
Copyright © 2011-2022 走看看