比赛 |
清华集训2017模板练习 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
找相同子串 |
最终得分 |
100 |
用户昵称 |
再见 |
运行时间 |
1.394 s |
代码语言 |
C++ |
内存使用 |
98.33 MiB |
提交时间 |
2017-07-17 17:34:18 |
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstring>
typedef long long LL;
int n,m,last,cnt,go[800010][26],pre[800010],len[800010],Q[800010],size[2][800010],sw[800010];
LL ans; char s1[200010],s2[200010];
void extend(int w){
int p=last,np=++cnt; len[np]=len[p]+1;
while(p&&!go[p][w]) go[p][w]=np,p=pre[p];
if(!p) pre[np]=1;
else{
int q=go[p][w];
if(len[q]==len[p]+1) pre[np]=q;
else{
int nq=++cnt; len[nq]=len[p]+1;
memcpy(go[nq],go[q],sizeof(go[0]));
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
while(p&&go[p][w]==q) go[p][w]=nq,p=pre[p];
}
}
last=np;
}
int main(){
freopen("find_2016.in","r",stdin);
freopen("find_2016.out","w",stdout);
scanf("%s%s",s1+1,s2+1);
n=strlen(s1+1);
m=strlen(s2+1);
last=cnt=1; for(int i=1;i<=n;i++) extend(s1[i]-'a');
last=1; for(int i=1;i<=m;i++) extend(s2[i]-'a');
int u=1;
for(int i=1;i<=n;i++){
u=go[u][s1[i]-'a'];
size[0][u]++;
}
u=1;
for(int i=1;i<=m;i++){
u=go[u][s2[i]-'a'];
size[1][u]++;
}
for(int i=1;i<=cnt;i++) sw[len[i]]++;
for(int i=1;i<=cnt;i++) sw[i]+=sw[i-1];
for(int i=1;i<=cnt;i++) Q[sw[len[i]]--]=i;
for(int i=cnt;i>=1;i--){
int a=Q[i];
size[0][pre[a]]+=size[0][a];
size[1][pre[a]]+=size[1][a];
}
for(int i=1;i<=cnt;i++)
ans+=1ll*size[0][i]*size[1][i]*(len[i]-len[pre[i]]);
printf("%lld\n",ans);
return 0;
}