思路:当前前缀串只属于某个前缀串的时候,才统计答案,但是样例WA了。。。
求助/kel
#include<cstdio>
#include<cctype>
#include<queue>
const int M=1e5+5;
struct Node{
int chi[26];
int f,len;
}SAM[M<<1];
struct Trie{
int chi[26];
int id;
}t[M];
int n,cnt,tot=1,ans[M],lst[M],pos[M<<1];
char s[M];
inline int Insert(int lst,int s,int i){
int q,p,nq,np;
p=lst;np=lst=++tot;
SAM[np].len=SAM[p].len+1;pos[np]=i;
for(;p&&!SAM[p].chi[s];p=SAM[p].f)SAM[p].chi[s]=np;
if(!p)SAM[np].f=1;
else{
q=SAM[p].chi[s];
if(SAM[q].len==SAM[p].len+1)SAM[np].f=q;
else{
nq=++tot;
pos[nq]=i;
SAM[nq]=SAM[q];
SAM[np].f=SAM[q].f=nq;
SAM[nq].len=SAM[p].len+1;
for(;p&&SAM[p].chi[s]==q;p=SAM[p].f)SAM[p].chi[s]=nq;
}
}
return np;
}
inline void Insert(int k,char*str){
int s,i,now=0;
for(i=0;isalpha(s=str[i]);++i){
s-=97;str[i]=0;
if(t[now].chi[s])t[t[now].chi[s]].id=0;
else t[t[now].chi[s]=++cnt].id=k;
now=t[now].chi[s];
}
}
inline void MakeSAM(){
std::queue<int>q;
int u,s;
lst[0]=1;
q.push(0);
while(!q.empty()){
u=q.front();q.pop();
for(s=0;s<26;++s){
if(t[u].chi[s]){
lst[t[u].chi[s]]=Insert(lst[u],s,t[u].id);
q.push(t[u].chi[s]);
}
}
}
}
signed main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;++i){
scanf("%s",s);
Insert(i,s);
}
MakeSAM();
for(i=1;i<=tot;++i)ans[pos[i]]+=SAM[i].len-SAM[SAM[i].f].len;
for(i=1;i<=n;++i)printf("%d\n",ans[i]);
}