比赛 清华集训2017模板练习 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 找相同子串 最终得分 100
用户昵称 辣鸡蒟蒻LCA 运行时间 3.873 s
代码语言 C++ 内存使用 109.03 MiB
提交时间 2017-12-02 21:07:08
显示代码纯文本
#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
const int MXA=26,MX=200005;

struct SAM_Node{
	SAM_Node *f,*t[MXA];int mx,dfn,dfe;
	vector<SAM_Node*>s;
	SAM_Node():f(NULL),mx(0){memset(t,0,sizeof(t)),s.clear();}
}pol[MX*4],*nn=pol,*rot=NULL;
SAM_Node *at[MX],*bt[MX];
int sa[MX*4],sb[MX*4];
char a[MX],b[MX];int n1,n2;

SAM_Node *ext(SAM_Node *p,char ch,int l){
	ch-='a';
	SAM_Node *np=nn++;np->mx=l;
	while(p&&!p->t[ch])p->t[ch]=np,p=p->f;
	if(!p)np->f=rot;
	else{
		SAM_Node *q=p->t[ch];
		if(q->mx==p->mx+1)np->f=q;
		else{
			SAM_Node *nq=nn++;*nq=*q;
			nq->mx=p->mx+1;
			q->f=np->f=nq;
			while(p&&p->t[ch]==q)p->t[ch]=nq,p=p->f;
		}
	}
	return np;
}
int dfc=0;
void dfs(SAM_Node *t){
	t->dfn=dfc++;
	for(vector<SAM_Node*>::iterator i=t->s.begin();i!=t->s.end();i++)dfs(*i);
	t->dfe=dfc;
}
int main(){
	int __size__ = 128 << 20;
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	freopen("find_2016.in","r",stdin);
	freopen("find_2016.out","w",stdout);
	//ios::sync_with_stdio(false);
	rot=nn++;
	cin>>a>>b;
	n1=strlen(a),n2=strlen(b);
	SAM_Node* t;t=rot;
	for(int i=0;i<n1;i++){at[i]=t=ext(t,a[i],i+1);}
	t=rot;bool flg=true;
	for(int i=0;i<n2;i++){flg=flg&&i<n1&&i<n2&&a[i]==b[i];bt[i]=t=(flg?at[i]:ext(t,b[i],i+1));}
	for(SAM_Node* i=pol+1;i<nn;i++)i->f->s.push_back(i);
	dfs(rot);
	for(int i=0;i<n1;i++)++sa[at[i]->dfn];
	for(int i=0;i<n2;i++)++sb[bt[i]->dfn];
	for(int i=dfc-1;i>=0;i--)sa[i]+=sa[i+1],sb[i]+=sb[i+1];
	LL ans=0;
	for(SAM_Node* i=pol+1;i<nn;i++)ans+=(LL)(i->mx-i->f->mx)*(sa[i->dfn]-sa[i->dfe])*(sb[i->dfn]-sb[i->dfe]);
	cout<<ans<<endl;
	return 0;
}