标签:
一篇文章由
单词都由小写字母组成。
令单词总长为
在
当然如果使用
令
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=1005000;
const int S=N<<1;
const int C=26;
int que[S],head,tail;
struct Node
{
int prt,len,size,deg;
int next[C];
}sam[S];
int tot;
int ins(int x,int c,int s)
{
int p=x,np=++tot;
for (sam[np].size=s,sam[np].len=sam[p].len+1;p&&!sam[p].next[c];p=sam[p].prt)
sam[p].next[c]=np;
if (!p)
sam[np].prt=1;
else
{
int q=sam[p].next[c];
if (sam[q].len==sam[p].len+1)
sam[np].prt=q;
else
{
int nq=++tot;
sam[nq]=sam[q],sam[nq].size=0;
sam[nq].len=sam[p].len+1;
sam[nq].prt=sam[q].prt;
sam[q].prt=sam[np].prt=nq;
for (;p&&sam[p].next[c]==q;p=sam[p].prt)
sam[p].next[c]=nq;
}
}
return np;
}
void calc()
{
for (int i=2;i<=tot;i++) sam[sam[i].prt].deg++;
for (int i=2;i<=tot;i++)
if (!sam[i].deg) que[++tail]=i;
int x;
while (head!=tail)
{
x=que[++head];
sam[sam[x].prt].size+=sam[x].size;
if (!--sam[sam[x].prt].deg&&x!=1)
que[++tail]=sam[x].prt;
}
}
struct Trie
{
int next[N][C],suf[N],size[N];
int tot;
int newnode()
{
for (int c=0;c<C;c++) next[tot][c]=0;
suf[tot]=size[tot]=0;
return tot++;
}
int insert(int rt,int c)
{
if (!next[rt][c]) next[rt][c]=newnode();
rt=next[rt][c],size[rt]++;
return rt;
}
void build(int rt)
{
for (int c=0,x;c<C;c++)
if (x=next[rt][c])
suf[x]=ins(suf[rt],c,size[x]),build(x);
}
}t;
char s[N];
int n,l;
int main()
{
freopen("word.in","r",stdin);
freopen("word.out","w",stdout);
scanf("%d",&n);
l=0;
t.tot++;
for (int i=1;i<=n;i++)
{
char ch=getchar();
int rt=0;
while (!isalpha(ch)) ch=getchar();
while (isalpha(ch)) s[l]=ch,rt=t.insert(rt,s[l++]-‘a‘),ch=getchar();
s[l++]=‘$‘;
}
t.suf[0]=tot=1;
t.build(0);
calc();
for (int i=1,cur=0,p;i<=n;i++)
{
p=1;
while (s[cur]!=‘$‘) p=sam[p].next[s[cur++]-‘a‘];
cur++;
printf("%d\n",sam[p].size);
}
fclose(stdin);
fclose(stdout);
}
标签:
原文地址:http://blog.csdn.net/a_crazy_czy/article/details/51334996