比赛 |
清华集训2017模板练习 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
找相同子串 |
最终得分 |
100 |
用户昵称 |
Cydiater |
运行时间 |
0.625 s |
代码语言 |
C++ |
内存使用 |
51.43 MiB |
提交时间 |
2017-07-17 15:08:29 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
#define FILE "find_2016"
const int MAXN=4e5+5;
const int oo=0x3f3f3f3f;
int N,M;
char s[MAXN],t[MAXN];
ll ans=0,LEN=0;
namespace SAM{
int p,q,np,nq,step[MAXN],pre[MAXN],son[MAXN][26],root=1,cnt=1;
int mark[MAXN],rnk[MAXN],R[MAXN],now=1;
ll con[MAXN];
void extend(int nxt){
p=now;now=np=++cnt;
step[np]=step[p]+1;
R[np]=1;
for(;p&&!son[p][nxt];p=pre[p])son[p][nxt]=np;
if(!p)pre[np]=root;
else{
q=son[p][nxt];
if(step[q]==step[p]+1)pre[np]=q;
else{
step[nq=++cnt]=step[p]+1;
memcpy(son[nq],son[q],sizeof(son[nq]));
pre[nq]=pre[q];
pre[np]=pre[q]=nq;
for(;son[p][nxt]==q;p=pre[p])son[p][nxt]=nq;
}
}
}
void Topsort(){
up(i,1,cnt)mark[step[i]]++;
up(i,1,N)mark[i]+=mark[i-1];
down(i,cnt,1)rnk[mark[step[i]]--]=i;
down(i,cnt,1){
int node=rnk[i];
R[pre[node]]+=R[node];
}
up(i,1,cnt){
int node=rnk[i];
con[node]=con[pre[node]]+R[node]*(step[node]-step[pre[node]]);
}
}
void Go(int nxt){
if(!now)now=root;
while(!son[now][nxt]){
now=pre[now];
LEN=step[now];
}
if(son[now][nxt]){
now=son[now][nxt];
LEN++;
ans+=con[pre[now]]+1LL*(LEN-step[pre[now]])*R[now];
}
}
}using namespace SAM;
namespace solution{
void Solve(){
scanf("%s%s",s+1,t+1);
N=strlen(s+1);M=strlen(t+1);
up(i,1,N)extend(s[i]-'a');
Topsort();
now=root;
up(i,1,M)Go(t[i]-'a');
cout<<ans<<endl;
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
Solve();
return 0;
}