题解 P6693 【谷歌翻(sheng)译(cao)机】
Upd on 2020.11.18:补充说明
题面传送门。
题意简述:给定两个字符串
A,B ,长度分别为n,m 。构造长度为k 的两个数列p,q 满足p_1=q_1=0,p_k=n,q_k=m,p_i<p_{i+1},q_i<q_{i+1} 且A_{p_i}=B_{q_i} (字符串下标从1 开始),则其权值为\sum (p_i-p_{i-1}-1)^2+(q_i-q_{i-1}-1)^2 。求所有这样的数列p,q 的权值之和。
显然有一个
设
设
那么有转移方程
不难发现这样转移是
不难看出
当然可以。显然
记
将上式与
答案即为
- 需要注意的是只有当
A_i=B_j 的时候柿子才能算入贡献。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e3+5;
const int mod=1e9+7;
ll pw[N],f[N][N],num[N][N],sumf[N][N],sumn[N][N],cons[N][N],delk[N][N],dell[N][N],ans;
string s,t;
int n,m;
void add(ll &x,ll y){
x+=y%mod;
if(x>=mod)x-=mod; if(x<0)x+=mod;
}
int main() {
for(int i=1;i<N;i++)pw[i]=i*i;
cin>>n>>m>>s>>t;
for(int i=0;i<=max(n,m);i++)sumn[i][0]=sumn[0][i]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(s[i-1]==t[j-1]){
f[i][j]=sumf[i-1][j-1],num[i][j]=sumn[i-1][j-1];
add(f[i][j],(pw[i]+pw[j]-2*i-2*j+2)%mod*sumn[i-1][j-1]+cons[i-1][j-1]);
add(f[i][j],-delk[i-1][j-1]*i-dell[i-1][j-1]*j);
add(ans,f[i][j]+num[i][j]*(pw[n-i]+pw[m-j]));
}
sumf[i][j]=(sumf[i-1][j]+sumf[i][j-1]-sumf[i-1][j-1]+f[i][j]+mod)%mod;
sumn[i][j]=(sumn[i-1][j]+sumn[i][j-1]-sumn[i-1][j-1]+num[i][j]+mod)%mod;
cons[i][j]=(cons[i-1][j]+cons[i][j-1]-cons[i-1][j-1]+num[i][j]*(pw[i]+pw[j]+2*i+2*j)+mod)%mod;
delk[i][j]=(delk[i-1][j]+delk[i][j-1]-delk[i-1][j-1]+num[i][j]*2*i%mod+mod*2)%mod;
dell[i][j]=(dell[i-1][j]+dell[i][j-1]-dell[i-1][j-1]+num[i][j]*2*j%mod+mod*2)%mod;
}
cout<<(ans+pw[n]+pw[m])%mod<<endl;
return 0;
}
求赞 qwq。