Matrix

小z 的女朋友送给小z 一个n×n的矩阵。但是矩阵实在太大了,小z 的女朋友拿不动,只能带给他两个长度为n 的整数序列l,t,分别作为矩阵F的第一行和第一列(保证(l_1=t_1)),并且告诉小z 矩阵可以通过如下方式得1:

(F(i,j)=a*F(i,j-1)+b*F(i-1,j))

现在小z 猜到了系数a,b,他想要计算F(n,n)模1e9+7的值。

样例输入
4 3 5
4 1 7 3
4 7 4 8
样例输出
59716
提示
对于前40%的数据,n≤5000;
对于另外20%的数据,a=0;
对于100%的数据,(n,a,v,l_i,t_ile10^5)

题解:很明显F(n,n)与除(1,1)外第一行和第一列的每个数有关,手膜可得点(x1,y1)对(x2,y2)的贡献为

(a^{x_2-x_1}*b^{y_2-y_1}* (x_1,y_1)(x_2,y_2))之间的路径条数

(0,0)到(n,m)的路径条数为(n+m choose m)( 只往右或往下走) 注意数组开两倍

[F(n,n)=sum A*x(x是第一行和第一列的每个数的数值,A是其系数) \ 对于t_i,A={2n-i-2 choose n-2}*a^{n-i}*b^{n-1}\ 对于l_i,A={2n-i-2 choose n-2}*a^{n-1}*b^{n-i} ]

代码: 明天再放 咕咕咕 没码完

#include<cstdio>
#define maxn 100001
#define int long long
const int mod=1e9+7;
using namespace std;
int n,a,b,l[maxn],t[maxn],ap,bp,pa=1,pb=1,jc[maxn<<1],ny[maxn<<1],ans=0,t1,t2;
//ap是a^(n-1),pa是a的累乘,b同 jc阶乘 ny逆元 
//t1,t2是组合数的系数 
int qpow(int a,int b){
	int az=1,base = a % mod;
	if(b == 0) return 1;
	while(b){
		if(b & 1) az = az * base % mod;
		base = base * base % mod;
		b >>= 1;} return az;}
inline int C(int x,int y){return jc[x]*ny[y]%mod*ny[x-y]%mod;}
signed main(){
	scanf("%d%d%d",&n,&a,&b);
	ap=qpow(a,n-1);bp=qpow(b,n-1);
	for(int i=1;i<=n;i++) scanf("%d",&l[i]);
	for(int i=1;i<=n;i++) scanf("%d",&t[i]);
	if(n == 1) {printf("%d
",l[1]%mod);return 0;}
	t1 = n-2; jc[0] = 1;
	for(int i=1;i <= (n<<1);i++) jc[i] = jc[i-1] * i % mod;
	ny[n*2] = qpow(jc[n*2],mod - 2);
	for(int i=(n<<1);i;i--) 
	ny[i-1] = ny[i] * i % mod;
	for(int i=n;i>1;i--,t1++,t2++,pa = pa*a%mod,pb = pb*b%mod)
	ans=((ans + l[i]*ap % mod* pb%mod *C(t1,t2)%mod) + (t[i]*bp%mod*pa%mod*C(t1,t2)%mod))%mod;
	printf("%d",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/shikeyu/p/13276629.html