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