1009 失恋的小 T(后缀数组¥)

1009: 失恋的小 T

时间限制: 1 Sec  内存限制: 128 MB
提交: 160  解决: 76
[提交][状态][讨论版]

题目描述

小 T 最近失恋了,开始怀疑人生和爱情,他想知道在这世界中去伪存真后还剩多少。 
小 T 在网上拿到了代表大千世界的长字符串,删掉了所有换行空格和标点符号,只剩下了小写字母。 
现在字符串中有好多重复的子串,相同子串里只有一个是 Real 的。 
为了让小 T 走出失恋,你一定要告诉他这个世界上 Real 的东西有多少。 
(子串:串中任意个连续的字符组成的子序列称为该串的子串) 

输入

包含 100 组输入,每组为一行字符串,只包含小写字母,长度 1-5000。 

输出

输出 100 行,每行一个整数,对应输入的答案。 

样例输入

aaba

样例输出

8

提示

后缀数组,

我还不会,,

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<math.h>
 4 #include <string>
 5 #include<string.h>
 6 #include<map>
 7 #include<queue>
 8 #include<set>
 9 #include<utility>
10 #include<vector>
11 #include<algorithm>
12 #include<stdlib.h>
13 using namespace std;
14 #define maxn 200100
15 #define maxm 200005
16 #define rd(x) scanf("%d", &x)
17 #define rd2(x, y) scanf("%d%d", &x, &y)
18 #define mod 1000000007
19 const int MAXN = 20010;
20 int t1[MAXN],t2[MAXN],c[MAXN];
21 bool cmp(int *r, int a,int b,int l){
22     return r[a] ==r[b] && r[a+l] == r[b+l];
23 }
24 void da(int str[], int sa[], int rankk[], int height[], int n, int m){
25     n++;
26     int i,j,p,*x =t1,*y=t2;
27     for(i =0; i <m; i++) c[i] =0;
28     for(i = 0; i <n; i++) c[x[i] =str[i]]++;
29     for(i =1; i < m; i++) c[i] += c[i-1];
30     for(i = n-1;i >= 0; i--) sa[--c[x[i]]] = i;
31     for(j =1; j <= n; j <<=1){
32         p =0;
33         for(i = n-j; i <n; i++) y[p++] = i;
34         for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] -j;
35 
36         for(i = 0; i < m; i++) c[i] =0;
37         for(i = 0 ;i < n; i++) c[x[y[i]]]++;
38         for(i = 1; i < m; i++) c[i] += c[i-1];
39         for(i = n-1; i >=0; i--) sa[--c[x[y[i]]]] = y[i];
40         swap(x,y);
41         p =1; x[sa[0]] =0;
42         for(int i = 1; i < n; i++) x[sa[i]] = cmp(y, sa[i-1], sa[i], j)?p-1:p++;
43         if(p >= n) break;
44         m =p;
45     }
46     int k =0;
47     n--;
48     for(i = 0; i <= n;i++) rankk[sa[i]] = i;
49     for(i = 0; i < n;i++){
50         if(k) k--;
51         j =sa[rankk[i]-1];
52         while(str[i+k] == str[j+k]) k++;
53         height[rankk[i]] = k;
54     }
55 }
56 int rankk[MAXN],height[MAXN];
57 char str[MAXN];
58 int r[MAXN],sa[MAXN];
59 int main()
60 {
61     int t = 100;
62     while(~scanf("%s", str)){
63         //scanf("%s", str);
64         int len = strlen(str);
65         //int n = 2*len +1;
66         for(int i =0; i < len ;i++) r[i] = str[i];
67         //for(int i =0; i < len; i++) r[len + 1 + i] = str[len -1 -i];
68         r[len] =0;
69         r[len+1] = 0;
70         da(r, sa, rankk, height,  len , 'z' + 1);
71         long long int res = len - sa[1];
72         for(int i= 2 ;i <= len; i++){
73             res = res + len - sa[i] -height[i];
74         }
75         printf("%lld
", res);
76     }
77     return 0;
78 }
原文地址:https://www.cnblogs.com/gongpixin/p/6790572.html