3 2 abab ab ba 1 aaa bbb 2 aaaa aa aaa
Case 1: 3 Case 2: 3 Case 3: 1
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=350010;
typedef long long ll;
char txt[maxn];
int sa[maxn],T1[maxn],T2[maxn],ct[maxn],he[maxn],rk[maxn],ans,n,m,lena;
int bi[maxn];
void getsa(char *st)
{
int i,k,p,*x=T1,*y=T2;
for(i=0; i<m; i++) ct[i]=0;
for(i=0; i<n; i++) ct[x[i]=st[i]]++;
for(i=1; i<m; i++) ct[i]+=ct[i-1];
for(i=n-1; i>=0; i--)
sa[--ct[x[i]]]=i;
for(k=1,p=1; p<n; k<<=1,m=p)
{
for(p=0,i=n-k; i<n; i++) y[p++]=i;
for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0; i<m; i++) ct[i]=0;
for(i=0; i<n; i++) ct[x[y[i]]]++;
for(i=1; i<m; i++) ct[i]+=ct[i-1];
for(i=n-1; i>=0; i--) sa[--ct[x[y[i]]]]=y[i];
for(swap(x,y),p=1,x[sa[0]]=0,i=1; i<n; i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
}
}
void gethe(char *st)
{
int i,j,k=0;
for(i=0;i<n;i++) rk[sa[i]]=i;
for(i=0;i<n-1;i++)
{
if(k) k--;
j=sa[rk[i]-1];
while(st[i+k]==st[j+k]) k++;
he[rk[i]]=k;
}
}
int main()
{
int t,cas=1,nm,i,nl,tp,bb;
ll ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&nm);
scanf("%s",txt);
n=lena=strlen(txt);
for(i=0;i<nm;i++)
{
txt[n++]='$';
scanf("%s",txt+n);
nl=strlen(txt+n);
n+=nl;
}
m=150;
n++;
getsa(txt);
gethe(txt);
n--;
ans=bb=0;
for(i=n;i>=1;i--)
{
if(sa[i]>=lena)
bb=he[i];
else
bi[i]=bb,bb=min(bb,he[i]);
}
for(i=1;i<=n;i++)
{
if(sa[i]<lena)
{
tp=lena-sa[i]-min(lena-sa[i],max(he[i],bi[i]));
ans+=tp;
}
}
printf("Case %d: %I64d\n",cas++,ans);
}
return 0;
}
hdu 4416 Good Article Good sentence(后缀数组&思维)
原文地址:http://blog.csdn.net/bossup/article/details/39506125