zoukankan      html  css  js  c++  java
  • 后缀数组:SPOJ SUBST1

    Given a string, we need to find the total number of its distinct substrings.

    Input

    T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000

    Output

    For each test case output one number saying the number of distinct substrings.

    Example

    Input:
    2
    CCCCC
    ABABA
    
    Output:
    5
    9

      题意:求一个字符串有多少不同子串
      LCP的应用,会打后缀数组的模板后就十分简单了
      后缀数组的理解:
      http://www.cnblogs.com/staginner/archive/2012/02/02/2335600.html
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 const int maxn=50010;
     7 char S[maxn];
     8 int r[maxn],wa[maxn],wb[maxn],wv[maxn],ws[maxn],sa[maxn];
     9 
    10 bool cmp(int *p,int i,int j,int l)
    11 {return p[i]==p[j]&&p[i+l]==p[j+l];}
    12 
    13 void DA(int n,int m)
    14 {
    15     int i,j,p,*x=wa,*y=wb,*t;
    16     for(i=0;i<m;i++)
    17         ws[i]=0;
    18     for(i=0;i<n;i++)
    19         ++ws[x[i]=r[i]];
    20     for(i=1;i<m;i++)
    21         ws[i]+=ws[i-1];
    22     for(i=n-1;i>=0;i--)
    23         sa[--ws[x[i]]]=i;
    24         
    25     for(j=1,p=1;p<n;j<<=1,m=p)
    26     {
    27         for(p=0,i=n-j;i<n;i++)
    28             y[p++]=i;
    29         for(i=0;i<n;i++)
    30             if(sa[i]>=j)
    31                 y[p++]=sa[i]-j;
    32         for(i=0;i<n;i++)
    33             wv[i]=x[y[i]];
    34         for(i=0;i<m;i++)
    35             ws[i]=0;    
    36         for(i=0;i<n;i++)
    37             ++ws[wv[i]];
    38         for(i=1;i<m;i++)            
    39             ws[i]+=ws[i-1];
    40         for(i=n-1;i>=0;i--)
    41             sa[--ws[wv[i]]]=y[i];
    42         for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
    43             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;        
    44     }
    45 }
    46 
    47 int rank[maxn],lcp[maxn];
    48 void LCP(int n)
    49 {
    50     int i,j,k=0;
    51     for(i=1;i<=n;i++)
    52         rank[sa[i]]=i;
    53     for(i=0;i<n;lcp[rank[i++]]=k)
    54         for(k?k--:k,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);    
    55 }
    56 
    57 int main()
    58 {
    59     int Q;
    60     scanf("%d",&Q);
    61     while(~scanf("%s",S))
    62     {
    63         int i,n;
    64         long long ans=0;
    65         for(i=0;S[i];i++)
    66         r[i]=S[i];
    67         DA(i+1,128);
    68         LCP(i);
    69         n=i;
    70         for(i=0;i<n;i++)
    71             ans+=n-i-lcp[rank[i]];
    72         printf("%d
    ",ans);    
    73     }
    74     return 0;
    75 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    jxl导入/导出excel
    iText导出pdf、word、图片
    Java CSV操作(导出和导入)
    Spring3.0+Hibernate+Atomikos集成构建JTA的分布式事务--解决多数据源跨库事务
    jQuery插件:跨浏览器复制jQuery-zclip
    微信小程序之表单提交
    微信小程序只之全局存储
    微信小程序之工具js封装与使用
    重构的艺术 深入认识
    重构的素养
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5193869.html
Copyright © 2011-2022 走看看