比赛 清华集训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;
}