• hdu3518


    题解:

    后缀数组

    枚举长度为k(1<=k<=len/2)的满足要求的子串个数

    代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1010;
    char str[N];
    int wa[N],wb[N],wv[N],Ws[N],sa[N],Rank[N],height[N];
    int cmp(int *r,int a,int b,int l)
    {
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void da(const char *r,int *sa,int n,int m) 
    {
        int *x=wa,*y=wb,*t;
        for (int i=0;i<m;i++) Ws[i]=0;
        for (int i=0;i<n;i++) Ws[x[i]=r[i]]++;
        for (int i=1;i<m;i++) Ws[i]+=Ws[i-1];
        for (int i=n-1;i>=0;i--) sa[--Ws[x[i]]]=i;
        for (int j=1,p=1;p<n;j*=2,m=p)
         {
             p=0;
            for (int i=n-j;i<n;i++) y[p++]=i;
            for (int i=0;i<n;i++)
             if (sa[i]>=j) y[p++]=sa[i]-j;
            for (int i=0;i<n;i++) wv[i]=x[y[i]];
            for (int i=0;i<m;i++) Ws[i]=0;
            for (int i=0;i<n;i++) Ws[wv[i]]++;
            for (int i=1;i<m;i++) Ws[i]+=Ws[i-1];
            for (int i=n-1;i>=0;i--) sa[--Ws[wv[i]]]=y[i];
            swap(x,y);x[sa[0]]=0;p=1;
            for (int i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
         }
        return;
    }
    void calheight(const char *r,int *sa,int n)
    {
        int j,k=0;
        for (int i=1;i<=n;i++) Rank[sa[i]]=i;
        for (int i=0;i<n;height[Rank[i++]]=k)
         for (k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++);
        return;
    }
    int solve(int k,int len)
    {
        int maxx=0,minn=INT_MAX,ans=0;
        for (int i=1;i<=len;i++)
         {
            if (height[i]>=k)
             maxx=max(maxx,max(sa[i-1],sa[i])),minn=min(minn,min(sa[i-1],sa[i]));
             else
              {
                if (maxx-minn>=k) ans++;
                maxx=0,minn=INT_MAX;
              }
         }
        if (maxx-minn>=k)ans++;
        return ans;
    }
    int main()
    {
        while (~scanf("%s",str) && strcmp(str,"#")!=0)
         {
            int len=strlen(str);
            da(str,sa,len+1,130);
            calheight(str,sa,len);
            ll ans=0;
            for (int i=1;i<=len/2;i++)ans+=solve(i,len);
            printf("%d
    ",ans);
         }
        return 0;
    }
  • 相关阅读:
    PHP 常用命令行
    windows环境下为php打开ssh2扩展
    mysql查看和修改注释
    PHP导出excel时数字变为科学计数的解决方法
    PHP获取上周、本周、上月、本月、本季度、上季度时间方法大全
    centos 基础修改文件权限
    使用apidocJs快速生成在线文档
    封装多线程处理大量数据操作
    android 中resources管理
    Android网格视图(GridView)
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8516215.html
Copyright © 2020-2023  润新知