看一眼题,觉得和3473好像啊,然而3473我还没做呢……
造一个广义后缀自动机,siz开成二维把两个串的siz分开来算,每个节点对答案的贡献为(mx[x]-mx[fa[x]])*siz[0][x]*siz[1][x]
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
using namespace std;
#define MAXN 800010
#define MAXM 1010
#define ll long long
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
int v[MAXN];
int p[MAXN];
struct sam{
int fa[MAXN],mx[MAXN],siz[2][MAXN],son[MAXN][26];
int rt,lst,tot;
sam(){
rt=lst=tot=1;
}
void ins(int x,int f){
int np=++tot,p=lst;
mx[np]=mx[p]+1;
while(p&&!son[p][x]){
son[p][x]=np;
p=fa[p];
}
if(!p){
fa[np]=rt;
}else{
int q=son[p][x];
if(mx[q]==mx[p]+1){
fa[np]=q;
}else{
int nq=++tot;
mx[nq]=mx[p]+1;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
while(p&&son[p][x]==q){
son[p][x]=nq;
p=fa[p];
}
}
}
lst=np;
}
void pre(){
int i;
memset(v,0,sizeof(v));
for(i=1;i<=tot;i++){
v[mx[i]]++;
}
for(i=1;i<=tot;i++){
v[i]+=v[i-1];
}
for(i=tot;i;i--){
p[v[mx[i]]--]=i;
}
for(i=tot;i;i--){
siz[0][fa[p[i]]]+=siz[0][p[i]];
siz[1][fa[p[i]]]+=siz[1][p[i]];
}
}
};
sam a;
char s1[MAXN],s2[MAXN];
int l1,l2;
bool visa[MAXN],visb[MAXN];
ll ans;
int main(){
int i;
scanf("%s%s",s1+1,s2+1);
l1=strlen(s1+1);
l2=strlen(s2+1);
int p=a.rt;
for(i=1;i<=l1;i++){
a.ins(s1[i]-'a',0);
p=a.son[p][s1[i]-'a'];
a.siz[0][p]++;
}
a.lst=1;
p=a.rt;
for(i=1;i<=l2;i++){
a.ins(s2[i]-'a',1);
p=a.son[p][s2[i]-'a'];
a.siz[1][p]++;
}
a.pre();
for(i=1;i<=a.tot;i++){
ans+=(ll)(a.mx[i]-a.mx[a.fa[i]])*a.siz[0][i]*a.siz[1][i];
}
printf("%lld\n",ans);
return 0;
}
/*
*/</span>