zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7574902.html
Copyright © 2011-2022 走看看