zoukankan      html  css  js  c++  java
  • spoj 705 求不同子串的个数(后缀数组)

    http://www.spoj.com/problems/SUBST1/

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

    解题思路:对于一个后缀sa[k],它产生了n-sa[k]个前缀,减去height[k]个相同的前缀(与前一个比较),则产生了n-sa[k]-height[k]个子串。累加后即结果。

    View Code
     1 /*
     2  *Author:       Zhaofa Fang
     3  *Created time: 2013-04-21-21.19
     4  *Language:     C++
     5  */
     6 #include <cstdio>
     7 #include <cstdlib>
     8 #include <sstream>
     9 #include <iostream>
    10 #include <cmath>
    11 #include <cstring>
    12 #include <algorithm>
    13 #include <string>
    14 #include <utility>
    15 #include <vector>
    16 #include <queue>
    17 #include <map>
    18 #include <set>
    19 using namespace std;
    20 
    21 typedef long long ll;
    22 #define DEBUG(x) cout<< #x << ':' << x << endl
    23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
    24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
    25 #define REP(i,n) FOR(i,0,n-1)
    26 #define REPD(i,n) FORD(i,n-1,0)
    27 #define PII pair<int,int>
    28 #define PB push_back
    29 #define MP make_pair
    30 #define ft first
    31 #define sd second
    32 #define lowbit(x) (x&(-x))
    33 #define INF (1<<30)
    34 
    35 const int maxn = 1111;
    36 char s[maxn];
    37 int sa[maxn],t1[maxn],t2[maxn],c[maxn];
    38 int rank[maxn],height[maxn];
    39 
    40 void getHeight(int n){
    41     int k = 0;
    42     for(int i=1;i<=n;i++)rank[sa[i]] = i;
    43     for(int i=0;i<n;i++){
    44         if(k)k--;
    45         int j = sa[rank[i]-1];
    46         while(s[i+k]==s[j+k])k++;
    47         height[rank[i]] = k;
    48     }
    49 }
    50 bool cmp(int *r,int a,int b,int l){
    51     return (r[a]==r[b] && r[a+l]==r[b+l]);
    52 }
    53 void build_sa(int m,int n){
    54     int i,*x=t1,*y=t2,k,p;
    55     for( i=0;i<m;i++)c[i] = 0;
    56     for( i=0;i<n;i++)c[x[i] = s[i]]++;
    57     for( i=1;i<m;i++)c[i] += c[i-1];
    58     for( i=n-1;i>=0;i--)sa[-- c[x[i]]] = i;
    59     for(k=1,p=0;p<n;m=p,k<<=1){
    60         p = 0;
    61         for(i=n-k;i<n;i++)y[p++] = i;
    62         for(i=0;i<n;i++)if(sa[i]>=k)y[p++] = sa[i]-k;
    63         for(i=0;i<m;i++)c[i] = 0;
    64         for(i=0;i<n;i++)c[x[y[i]]]++;
    65         for(i=1;i<m;i++)c[i] += c[i-1];
    66         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]] = y[i];
    67         swap(x,y);
    68         p = 1; x[sa[0]] = 0;
    69         for(i=1;i<n;i++)
    70             x[sa[i]] = cmp(y,sa[i-1],sa[i],k)?p-1:p++;
    71     }
    72     getHeight(n-1);
    73 }
    74 int solve(int n){
    75     int ans = n - sa[1];
    76     for(int i=2;i<=n;i++){
    77         ans += n-sa[i]-height[i];
    78     }
    79     return ans;
    80 }
    81 int main(){
    82     //freopen("in","r",stdin);
    83     //freopen("out","w",stdout);
    84     int T;
    85     cin>>T;
    86     while(T--){
    87         scanf("%s",s);
    88         int n = strlen(s);
    89         build_sa(255,n+1);
    90         printf("%d\n",solve(n));
    91     }
    92     return 0;
    93 }
    by Farmer
  • 相关阅读:
    PHP中单引号与双引号的区别分析
    utf8_unicode_ci与utf8_general_ci的区别
    [mysql-Ver5.6.23] windows版my.ini配置
    Gateway/Worker模型 数据库使用示例
    php 字符串 以 开头 以结尾 startWith endWith
    MySQL错误ERROR 2002 (HY000): Can't connect to local MySQL server
    vim变ide
    在Vue中使用样式
    Vue指令之`v-model`和`双向数据绑定
    Vue指令之事件修饰符
  • 原文地址:https://www.cnblogs.com/fzf123/p/3034615.html
Copyright © 2011-2022 走看看