• SPOJ Distanct Substrings(求不同子串的数量)


    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 <= 1000

    Output

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

    Example

    Sample Input:
    2
    CCCCC
    ABABA

    Sample Output:
    5
    9

    Explanation for the testcase with string ABABA: 
    len=1 : A,B
    len=2 : AB,BA
    len=3 : ABA,BAB
    len=4 : ABAB,BABA
    len=5 : ABABA
    Thus, total number of distinct substrings is 9.

    题解:题意就是让你求子串的种类;

    思路:后缀数组,然后每个字符的贡献为n-sa[i]-height[i];(n为字符的个数);

    参考代码:

     1 //#include<bits/stdc++.h>
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<string>
     6 #include<cstdlib>
     7 #include<cmath>
     8 #include<algorithm>
     9 using namespace std;
    10 #define clr(a,val) memset(a,val,sizeof(a))
    11 #define lowbit(x) x&-x
    12 #define eps 1e-6
    13 typedef long long ll;
    14 const int INF=0x3f3f3f3f;
    15 const int maxn=1010;
    16 struct SuffixArray{
    17     int s[maxn];
    18     int sa[maxn],height[maxn],rank[maxn],n;
    19     int t[maxn*2],t2[maxn*2];
    20     int cnt[maxn];
    21     void build_sa(int m)//字符都属于0~m-1范围 
    22     {
    23         int i,*x=t,*y=t2;
    24         for(i=0;i<m;i++) cnt[i]=0;
    25         for(i=0;i<n;i++) cnt[x[i]=s[i]]++;
    26         for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
    27         for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; 
    28         for(int k=1,p;k<=n;k <<=1)//k<=n
    29         {
    30             p=0;
    31             for(i=n-k;i<n;i++) y[p++]=i;
    32             for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
    33             for(i=0;i<m;i++) cnt[i]=0;
    34             for(i=0;i<n;i++) cnt[x[y[i]]]++;
    35             for(i=1;i<m;i++) cnt[i]+=cnt[i-1];
    36             for(i=n-1;i>=0;i--) sa[--cnt[x[y[i]]]]=y[i];
    37             swap(x,y);
    38             p=1;x[sa[0]]=0;
    39             for(i=1;i<n;i++)
    40                    x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]? p-1:p++;
    41             if(p>=n) break;
    42             m=p;
    43         }
    44     }
    45     void build_height()
    46     {
    47         int k=0;
    48         for(int i=0;i<n;i++) rank[sa[i]]=i;
    49         for(int i=0;i<n-1;i++)
    50         {
    51             if(k) k--;
    52             int j=sa[rank[i]-1];
    53             while(s[i+k]==s[j+k]) k++;
    54             height[rank[i]]=k;
    55         }
    56     }
    57 } SA;
    58 int main()
    59 {
    60     int n, m, t;
    61     string str;
    62     cin>>t;
    63     while(t--) 
    64     {
    65         cin>>str;
    66         int n = str.size();
    67         for(int i = 0; i<n; i++) SA.s[i] = str[i];
    68         SA.s[n] = 0;SA.n=n+1;
    69         SA.build_sa(128);
    70         SA.build_height();
    71         int ans = 0;
    72         for(int i=1;i<=n;i++) ans+=n-SA.sa[i]-SA.height[i];
    73         cout<<ans<<endl;
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    《Web 开发基础》专题系列
    《.NET 编程结构》专题汇总(C#)
    .NET Core:使用BarTender
    .NET Core:过滤器
    .NET Core:中间件
    .NET Core:Api版本控制
    .NET Core:Token认证
    .NET Core:SignalR
    .NET Core:跨域
    .NET Core:Json和XML
  • 原文地址:https://www.cnblogs.com/csushl/p/10048274.html
Copyright © 2020-2023  润新知