Distinct Substrings (spoj694)(后缀数组)

Posted zhangbuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Distinct Substrings (spoj694)(后缀数组)相关的知识,希望对你有一定的参考价值。

核心:每一个后缀的每一个前缀都是一个子串

相邻后缀的lcp的值是就是重复子串的个数

用所有的子串减去sigma(height)就行了

 

 1 #include"bits/stdc++.h"
 2 using namespace std;
 3 #define clr(x) memset(x,0,sizeof(x))
 4 
 5 int T;
 6 char a[2000];
 7 int n,m;
 8 int x[2000],y[2000],c[2000];
 9 int sa[2000];
10 int rk[2000];
11 int ht[2000];
12 
13 inline void SA()
14 {
15    //cout<<"%^("<<endl;
16 
17    // cout<<n<<" "<<m<<endl;
18  //cout<<a+1<<endl;
19    /* memset(c,0,sizeof c);
20     memset(x,0,sizeof x);
21     memset(y,0,sizeof y);*/
22     clr(c);
23     clr(x);
24     clr(y);
25 
26 
27    for (int i=1;i<=n;i++) ++c[x[i] = a[i]-A];
28    for (int i=1;i<=m;i++) c[i]+=c[i-1];
29    for (int i=n;i;i--) sa[c[x[i]]--] = i;
30 
31    for (int k=1;k<=n;k*=2)
32    {
33 
34       int num = 0;
35       for (int i=n-k+1;i<=n;i++) y[++num] = i;
36       for (int i=1;i<=n;i++) if (sa[i]>k) y[++num] = sa[i]-k;
37       memset(c,0,sizeof c);
38       for (int i=1;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;i;i--) sa[c[x[y[i]]]--] = y[i],y[i]=0;
41       num=1;
42       swap(x,y);
43       x[sa[1]]=1;
44 
45       for (int i=2;i<=n;i++)
46       {
47         x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
48       }
49 
50       if (num==n) break;
51       m=num;
52 
53 
54    }
55 
56    for (int i=1;i<=n;i++) rk[sa[i]] = i;
57    int k = 0;
58 
59    for (int i=1;i<=n;i++)
60    {
61       if (rk[i]==1) continue;
62       if (k) k--;
63       int j =sa[rk[i]-1];
64 
65 
66       while (a[i+k]==a[j+k]&&i+k<=n&&j+k<=n) k++;
67 
68       ht[rk[i]] = k;
69    }
70 
71 //
72    //  for (int i=1;i<=n;i++ ) cout<<ht[i]<<" ";cout<<endl;
73   // /   / for (int i=1;i<=n;i++) cout<<sa[i]<<" ";cout<<endl;
74 
75 
76 }
77 
78 
79 
80 int main()
81 {
82   cin>>T;
83   while (T--)
84   {
85 
86     m=233;
87     cin>>a+1;
88     n = strlen(a+1);
89     SA();
90 
91   int ans = n*(n+1)/2;
92   for (int i=1;i<=n;i++ ) ans -= ht[i];
93   cout<<ans<<endl;
94 
95 
96 
97   }

 

以上是关于Distinct Substrings (spoj694)(后缀数组)的主要内容,如果未能解决你的问题,请参考以下文章

关于在eclipse for  javaee中修改servlet新建模板

Java基础(正式上课第二天)

全角半角字符对照表

4 Values whose Sum is 0 poj2785

使用JdbcTemplate和JdbcDaoSupport

深度学习-机器视觉学习路线