题目大意:RT
分析:练手题目....后缀数组确实很强大.....多理解height数组, 切勿使用模版,后缀数组本身就有很多细节,多犯错更有利理解这个算法。
代码如下:
=====================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = ; 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)+;
x = tempx, y = tempy, MaxId=; for(int i=; 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-]+len>N)
return false;
if(y[sa[i]] != y[sa[i-]] || y[sa[i]+len] != y[sa[i-]+len])
return false; return true;
}
void BaseSort()
{
for(int i=; i<MaxId; i++)
sum[i] = ;
for(int i=; i<N; i++)
sum[ x[ y[i] ] ] += ;
for(int i=; i<MaxId; i++)
sum[i] += sum[i-];
for(int i=N-; i>=; i--)
sa[ --sum[ x[ y[i] ] ] ] = y[i];
}
void GetSa()
{
BaseSort(); for(int len=; len<=N; len<<=)
{
int id = ; for(int i=N-len; i<N; i++)
y[id++] = i;
for(int i=; i<N; i++)if(sa[i] >= len)
y[id++] = sa[i]-len; BaseSort();
swap(x, y);
x[ sa[] ] = id = ; for(int i=; i<N; i++)
{
if(cmp(i, len) == true)
x[sa[i]] = id;
else
x[sa[i]] = ++id;
} MaxId = id+; if(MaxId >= N)break;
}
}
void GetHeight()
{
for(int i=; i<N; i++)
rank[sa[i]] = i; for(int k=, i=; i<N; i++)
{
if(!rank[i])
{
height[] = k = ;
continue;
}
if(k)k--; int pre = sa[ rank[i]- ]; while(text[i+k] == text[pre+k])
k++;
height[rank[i]] = k;
}
}
int TotalSonArr()
{
int sum = ; for(int i=; i<N; i++)
sum += N-sa[i]--height[i]; return sum;
}
void debug(int p[])
{
for(int i=; 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 ;
}