• SPOJ 694 Distinct Substrings(不相同子串个数)


    https://vjudge.net/problem/SPOJ-DISUBSTR

    题意:

    给定一个字符串,求不相同的子串的个数。

    思路:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn=1000+5;
    16 
    17 int n;
    18 char s[maxn];
    19 int sa[maxn],t[maxn],t2[maxn],c[maxn];
    20 int Rank[maxn],height[maxn];
    21 
    22 void build_sa(int m)
    23 {
    24     int *x=t,*y=t2;
    25     //基数排序
    26     for(int i=0;i<m;i++)    c[i]=0;
    27     for(int i=0;i<n;i++)    c[x[i]=s[i]]++;
    28     for(int i=1;i<m;i++)    c[i]+=c[i-1];
    29     for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
    30     for(int k=1;k<=n;k<<=1)
    31     {
    32         int p=0;
    33         //直接利用sa数组排序第二关键字
    34         for(int i=n-k;i<n;i++)  y[p++]=i;
    35         for(int i=0;i<n;i++)    if(sa[i]>=k)    y[p++]=sa[i]-k;
    36         //基数排序第一关键字
    37         for(int i=0;i<m;i++)    c[i]=0;
    38         for(int i=0;i<n;i++)    c[x[y[i]]]++;
    39         for(int i=1;i<m;i++)    c[i]+=c[i-1];
    40         for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
    41         //根据sa和y计算新的x数组
    42         swap(x,y);
    43         p=1;
    44         x[sa[0]]=0;
    45         for(int i=1;i<n;i++)
    46             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
    47         if(p>=n)
    48             break;
    49         m=p;                //下次基数排序的最大值
    50     }
    51 }
    52 
    53 void getHeight(int n)
    54 {
    55     int i,j,k=0;
    56     for(i=1;i<=n;i++)  Rank[sa[i]]=i;
    57     for(i=0;i<n;i++)
    58     {
    59         if(k)  k--;
    60         int j=sa[Rank[i]-1];
    61         while(s[i+k]==s[j+k])  k++;
    62         height[Rank[i]]=k;
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     //freopen("in.txt","r",stdin);
    69     int T;
    70     scanf("%d",&T);
    71     while(T--)
    72     {
    73         scanf("%s",s);
    74         n=strlen(s);
    75         s[n]='0';
    76         n++;
    77         build_sa(128);
    78         getHeight(n-1);
    79         int ans=(n-1)*n/2;
    80         for(int i=1;i<n;i++)
    81             ans-=height[i];
    82         printf("%d
    ",ans);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    linux学习方法之一
    HDU 1556 Color the ball
    Object-c学习之路十(NSNumber&NSValue)
    蜂鸣器驱动方式源程序--有源无源通用
    Wordpress更换主题之后出错
    mybatis_Generator配置
    Logistic Regression
    求两个字符串的最大公共字串
    数据结构排序系列详解之二 希尔排序
    《mysql必知必会》学习_第五章
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7574902.html
Copyright © 2020-2023  润新知