matrix

【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模 1 0 9 + 7 {10^9+7} 109+7的值。
输入
第一行三个整数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, l i l_i li, t i t_i ti 1 0 5 10^5 105
题解:
明显 F n , n Fn,n Fn,n与除(1,1)外的第一行和第一列的每个数有关,即 F n , n = ∑ A ∗ x Fn,n=\sum A*x Fn,n=Ax(x是第一行和第一列的每个数的数值,A是其系数)
考虑怎么求系数,可以发现每次向右则乘a ,向下则乘b,总共的贡献就是累乘的数 ∗ * 从该点到右下角的路径数(即蚂蚁路径)
对于 t i t_i ti A = ( n − 2 2 n − i − 2 ) ∗ a n − i ∗ b n − 1 A={(^{2n-i-2}_{n-2})}*a^{n-i}*b^{n-1} A=(n22ni2)anibn1
对于 l i l_i li A = ( n − 2 2 n − i − 2 ) ∗ a n − 1 ∗ b n − i A={(^{2n-i-2}_{n-2})}*a^{n-1}*b^{n-i} A=(n22ni2)an1bni
代码如下

#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\n",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\n",ans),0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值