题目大意:RT
分析:练手题目....后缀数组确实很强大.....多理解height数组, 切勿使用模版,后缀数组本身就有很多细节,多犯错更有利理解这个算法。
代码如下:
=====================================================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN = 1007; struct SuffixArr { int tempx[MAXN], tempy[MAXN], text[MAXN]; int rank[MAXN], sa[MAXN], sum[MAXN], height[MAXN]; int *x, *y, N, MaxId; void GetText(char s[]) { N = strlen(s)+1; x = tempx, y = tempy, MaxId=300; for(int i=0; i<N; i++) { text[i] = x[i] = (int)s[i]; y[i] = i; } } bool cmp(int i, int len) { if(sa[i]+len>N || sa[i-1]+len>N) return false; if(y[sa[i]] != y[sa[i-1]] || y[sa[i]+len] != y[sa[i-1]+len]) return false; return true; } void BaseSort() { for(int i=0; i<MaxId; i++) sum[i] = 0; for(int i=0; i<N; i++) sum[ x[ y[i] ] ] += 1; for(int i=1; i<MaxId; i++) sum[i] += sum[i-1]; for(int i=N-1; i>=0; i--) sa[ --sum[ x[ y[i] ] ] ] = y[i]; } void GetSa() { BaseSort(); for(int len=1; len<=N; len<<=1) { int id = 0; for(int i=N-len; i<N; i++) y[id++] = i; for(int i=0; i<N; i++)if(sa[i] >= len) y[id++] = sa[i]-len; BaseSort(); swap(x, y); x[ sa[0] ] = id = 0; for(int i=1; i<N; i++) { if(cmp(i, len) == true) x[sa[i]] = id; else x[sa[i]] = ++id; } MaxId = id+1; if(MaxId >= N)break; } } void GetHeight() { for(int i=0; i<N; i++) rank[sa[i]] = i; for(int k=0, i=0; i<N; i++) { if(!rank[i]) { height[0] = k = 0; continue; } if(k)k--; int pre = sa[ rank[i]-1 ]; while(text[i+k] == text[pre+k]) k++; height[rank[i]] = k; } } int TotalSonArr() { int sum = 0; for(int i=0; i<N; i++) sum += N-sa[i]-1-height[i]; return sum; } void debug(int p[]) { for(int i=0; i<N; i++) printf("%d ", p[i]); printf("\n"); } }; SuffixArr suf; char s[MAXN]; int main() { int T; scanf("%d", &T); while(T--) { scanf("%s", s); suf.GetText(s); suf.GetSa(); suf.GetHeight(); int ans = suf.TotalSonArr(); printf("%d\n", ans); } return 0; }
时间: 2024-12-24 22:24:24