Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 1625 Solved: 749
[Submit][Status][Discuss]
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
3
a
aa
aaa
Sample Output
6
3
1
后缀数组/AC自动机fail树
①后缀数组的方法比较简单,只要把所有的字符串串在一起,两两之间用其他符号连接。
求出
②AC自动机需要建出fail树(即把fail指针反向得出的树),那么一个字符串出现的次数就是他的儿子的出现的次数之和。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define M 1001000
using namespace std;
int wv[M],c[M],x[M],y[M],r[M],wa[M],wb[M],sa[M],rk[M],he[M],pos[205],l[205];
char s[M];
int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r,int sa[],int n,int m)
{
int *x=wa,*y=wb,*t;
for (int i=0;i<m;i++) c[i]=0;
for (int i=0;i<n;i++) c[x[i]=r[i]]++;
for (int i=1;i<m;i++) c[i]+=c[i-1];
for (int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
int i,j,p;
for (j=1,p=1;p<n;j*=2,m=p)
{
for (p=0,i=n-j;i<n;i++) y[p++]=i;
for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
for (i=0;i<n;i++) wv[i]=x[y[i]];
for (i=0;i<m;i++) c[i]=0;
for (i=0;i<n;i++) c[wv[i]]++;
for (i=1;i<m;i++) c[i]+=c[i-1];
for (i=n-1;i>=0;i--) sa[--c[wv[i]]]=y[i];
for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
}
void Calheight(int *r,int *sa,int n)
{
int i,j,k=0;
for (i=1;i<=n;i++)
rk[sa[i]]=i;
for (i=0;i<n;i++)
{
if (k) k--;
j=sa[rk[i]-1];
while (r[j+k]==r[i+k])
k++;
he[rk[i]]=k;
}
}
int main()
{
int n;
scanf("%d",&n);
int len=-1;
for (int i=1;i<=n;i++)
{
scanf("%s",s);
l[i]=strlen(s);
pos[i]=len+1;
for (int j=0;j<l[i];j++)
r[++len]=s[j]-‘a‘+1;
r[++len]=27;
}
r[++len]=0;
da(r,sa,len+1,28);
Calheight(r,sa,len);
for (int i=1;i<=n;i++)
{
int j,x=rk[pos[i]],le,ri;
for (j=x;j&&he[j]>=l[i];j--);
le=j+1;
for (j=x+1;j<=len&&he[j]>=l[i];j++);
ri=j-1;
printf("%d\n",ri-(le-1)+1);
}
return 0;
}
WA是因为没有在字符串后面补0。
为什么要在字符串后面补0呢?
如果字符串后面两位都是a,那么当
在j>1的排序中,根据cmp函数,如果a或者b>n-j,第一个相等条件就一定不满足,也就不存在第二个判断的时候越界的情况了。
综上,补0只在
原文地址:http://blog.csdn.net/regina8023/article/details/45095319