【from new_dtoj 3968: matrix】
题目描述
小z 的女朋友送给小z 一个n×n的矩阵。但是矩阵实在太大了,小z 的女朋友拿不动,只能带给他两个长度为n 的整数序列l,t,分别作为矩阵F的第一行和第一列(保证l1=t1),并且告诉小z 矩阵可以通过如下方式得到:Fi,j=a∗Fi,j−1+b∗Fi−1,j
现在小z 猜到了系数a,b,他想要计算Fn,n模的值。
输入
第一行三个整数n,a,b。
第二行n个数表示t。
第三行n个数表示l。
输出
一行一个整数表示答案。
样例输入
4 3 5
4 1 7 3
4 7 4 8
样例输出
59716
提示
对于前40%的数据,n≤5000;
对于另外20%的数据,a=0;
对于100%的数据,n,a,v,,≤。
题解:
明显与除(1,1)外的第一行和第一列的每个数有关,即(x是第一行和第一列的每个数的数值,A是其系数)
考虑怎么求系数,可以发现每次向右则乘a ,向下则乘b,总共的贡献就是累乘的数从该点到右下角的路径数(即蚂蚁路径)
对于,
对于,
代码如下
#include <cstdio>
#include <string>
#define _(d) while(d(isdigit(c=getchar())))
using namespace std;
inline int R(){
int x,f=1;char c;_(!)c=='-'?f=0:f;x=(c^48);
_()x=(x<<3)+(x<<1)+(c^48);return f?x:-x;
}
const int P=1e9+7,N=1e5+5;
int n,a,b,l[N],t[N],ap,bp,pa=1,pb=1,jc[N*2],ny[N*2],ans,t1,t2;
//ap是a^(n-1),pa是a的累乘,b类同
//t1,t2是组合数的系数
inline int K(int x,int y){
int A=1;
while(y){
if (y&1) A=1ll*A*x%P;
x=1ll*x*x%P;y>>=1;
}
return A;
}
inline int C(int x,int y){return 1ll*jc[x]*ny[y]%P*ny[x-y]%P;}
int main(){
n=R();a=R();b=R();ap=K(a,n-1);bp=K(b,n-1);
for (int i=1;i<=n;i++) l[i]=R();
for (int i=1;i<=n;i++) t[i]=R();
if (n==1){printf("%d
",l[1]%P);return 0;}
t1=n-2;jc[0]=1;for (int i=1;i<=n*2;i++) jc[i]=1ll*jc[i-1]*i%P;
ny[n*2]=K(jc[n*2],P-2);for (int i=n*2;i;i--) ny[i-1]=1ll*ny[i]*i%P;
for (int i=n;i>1;i--,t1++,t2++,pa=1ll*pa*a%P,pb=1ll*pb*b%P)
ans=((1ll*ans+1ll*l[i]*ap%P*pb%P*C(t1,t2)%P)%P+1ll*t[i]*bp%P*pa%P*C(t1,t2)%P)%P;
return printf("%d
",ans),0;
}