1009: 失恋的小 T
时间限制: 1 Sec 内存限制: 128 MB提交: 160 解决: 76
[提交][状态][讨论版]
题目描述
小 T 最近失恋了,开始怀疑人生和爱情,他想知道在这世界中去伪存真后还剩多少。
小 T 在网上拿到了代表大千世界的长字符串,删掉了所有换行空格和标点符号,只剩下了小写字母。
现在字符串中有好多重复的子串,相同子串里只有一个是 Real 的。
为了让小 T 走出失恋,你一定要告诉他这个世界上 Real 的东西有多少。
(子串:串中任意个连续的字符组成的子序列称为该串的子串)
小 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 }