zoukankan      html  css  js  c++  java
  • spoj694--Distinct Substrings

    个人第一道后缀数组题目。
    对于每一个后缀suffix(i),都有len-sa[i]个前缀(也即有len-sa[i]个不同的字符串),其中与排名前一位的后缀有height[i]个共同的前缀,最后所得到的新的字符串个数为len-sa[i]-height[i].因此这题只要求出sa以及height即可求得答案。

    #include<stdio.h>
    #include<string.h>
     #define maxn 100010
     int wa[maxn];
     int wb[maxn];
     int wv[maxn];
     int wsa[maxn];
     int ranks[maxn],height[maxn];
     
     void calheight(int *r,int *sa,int n)
     {
          int i,j,k=0;
          for(i=1;i<=n;i++) ranks[sa[i]]=i;
          for(i=0;i<n ;height[ranks[i++]]=k)
          for(k?k--:0,j=sa[ranks[i]-1];r[i+k]==r[j+k];k++);
          return;
     }
     
     int cmp(int *r,int a,int b,int l)
     {
         return r[a]==r[b]&&r[a+l]==r[b+l];
     };
     
     void da(int *r,int *sa,int n,int m)
     {
          int i,j,p,*x=wa,*y=wb,*t;
          for(i=0;i<m;i++) wsa[i]=0;
          for(i=0;i<n;i++) wsa[x[i]=r[i]]++;
          for(i=1;i<m;i++) wsa[i]+=wsa[i-1];
          for(i=n-1;i>=0;i--) sa[--wsa[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++) wsa[i]=0;
           for(i=0;i<n;i++) wsa[wv[i]]++;
           for(i=1;i<m;i++) wsa[i]+=wsa[i-1];
           for(i=n-1;i>=0;i--) sa[--wsa[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++;
           }
           return;
     }
     
     int r[maxn];
     int sa[maxn];
     int main()
     {
         char str[maxn];
         int t,i;
         scanf("%d",&t);
         while(t--)
         {
             scanf("%s",str);
             memset(r, 0 ,sizeof(r));
             memset(sa, 0, sizeof(sa));
             int len = strlen(str);
             for (i = 0 ; i < len; ++i)
             {
                 r[i] = (int)str[i];
             }
             da(r, sa, len + 1 , 150);
             calheight(r, sa, len);
             int sum = 0;
             for(i=0;i<len;i++)
                 sum += len-sa[i+1]-height[i+1];
             printf("%d
    ",sum);
         }
         return 0;
     }
  • 相关阅读:
    不同长度的数据进行位运算
    Linux的sleep()和usleep()的使用和区别
    linux inode已满解决方法
    Debian 系统修改语言设置成英文
    IIS设置问题
    Ajax实现跨域访问的三种方法
    HTML--备忘点
    C#基础---值类型和引用类型
    dapper.net框架使用随笔
    WebService的搭建,部署,简单应用和实体类结合使用
  • 原文地址:https://www.cnblogs.com/tengtao93/p/3907565.html
Copyright © 2011-2022 走看看