您的位置:首页 > 其它

【jzoj5315】【NOIP2017提高A组模拟8.19】【小串串】【sam 】

2017-08-19 17:24 633 查看

description



solution

构出sam,求出fail树子树大小,贡献为size[x]^2*(mx[fa[x]]-mx[x])。

code

#include<set>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long
#define ULL unsigned long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
using namespace std;
int const mn=1e5+9,mp=2*1e5+9,mo=1e9+7;
int t,n,f[mp],mx[mp],fa[mp],son[mp][26],a[mp];
char s[mn];
bool cmp(int x,int y){
return mx[x]<mx[y];
}
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%d",&t);
fo(cas,1,t){
scanf("%s",s+1);
n=strlen(s+1);
fo(i,1,n)s[i]-='a';
int pon=1,last=1;
fo(ii,1,n){
int p=last,np=last=++pon,ch=s[ii];
mx[np]=mx[p]+1;f[np]=1;
for(;p&&(!son[p][ch]);p=fa[p])son[p][ch]=np;
if(!p){fa[np]=1;continue;}
int q=son[p][ch];
if(mx[p]+1==mx[q])fa[np]=q;
else{
int nq=++pon;
mx[nq]=mx[p]+1;
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
fo(i,0,25)son[nq][i]=son[q][i];
for(;p&&(son[p][ch]==q);p=fa[p])son[p][ch]=nq;
}
}
fo(i,1,pon)a[i]=i;
sort(a+1,a+pon+1,cmp);
LL ans=0;
fd(i,pon,2){
int p=a[i];
f[fa[p]]+=f[p];
ans+=1ll*(mx[p]-mx[fa[p]])*f[p]*f[p];
}
printf("%lld\n",ans);
fo(i,1,pon){
mx[i]=fa[i]=f[i]=0;
fo(j,0,25)son[i][j]=0;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: