Noip模拟题 Matrix [递推,组合数]

时间:2023-03-09 04:09:42
Noip模拟题 Matrix [递推,组合数]

Matrix

时间限制: 1 Sec  内存限制: 512 MB

题目描述

小 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 模 109 + 7 的值

输入

第一行三个整数 n, a, b.
第二行 n 个数表示 l.
第三行 n 个数表示 t

输出

一行一个整数表示答案    

样例输入

4 3 5
4 1 7 3
4 7 4 8

样例输出

59716

提示

对于前 40% 的数据,n ≤ 5000;
对于另外 20% 的数据,a = 0;
对于 100% 的数据,n, a, v, li, ti ≤ 105

  分析:

   大力推公式。

  反正就从给定的公式下手,可以推出$f[n][n]$与$f[1][1\thicksim n]$和$f[1\thicksim n][1]$的关系,当然很显然需要用到组合。

  实际上,$f[n][n]$只由$f[1][1\thicksim n]$和$f[1\thicksim n][1]$中的元素得到,并且从$f[1][1\thicksim n]$和$f[1\thicksim n][1]$的任一元素转移到$f[n][n]$的转移方式都是唯一的,这里推导过程就不再写了,直接写出结论:

$f[n][n]=\sum^n_{i=1}(f[1][i]*a^{n-1}*b^{n-i}*C^{n*2-i-2}_{n-2})+\sum^n_{i=1}(f[i][1]*a^{n-i}*b^{n-1}*C^{n*2-i-2}_{n-2})$

  Code:

//It is made by HolseLee on 25th Oct 2018
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mod (1000000007)
using namespace std; typedef long long ll;
const ll N=2e5+;
ll n,tot,A,B,x[N],y[N],a[N],b[N],aa[N],bb[N],ans; inline ll read()
{
char ch=getchar(); ll num=; bool flag=false;
while( ch<'' || ch>'' ) {
if( ch=='-' ) flag=true; ch=getchar();
}
while( ch>='' && ch<='' ) {
num=num*+ch-''; ch=getchar();
}
return flag ? -num : num;
} void ready()
{
tot=(n-)<<;
a[]=a[]=b[]=b[]=; aa[]=bb[]=, aa[]=A, bb[]=B;
for(ll i=; i<=tot; ++i) b[i]=b[i-]*i%mod;
for(ll i=; i<=tot; ++i) a[i]=(mod-mod/i)*a[mod%i]%mod;
for(ll i=; i<=tot; ++i) a[i]=a[i]*a[i-]%mod;
for(ll i=; i<=n; ++i) aa[i]=aa[i-]*A%mod;
for(ll i=; i<=n; ++i) bb[i]=bb[i-]*B%mod;
} inline ll getx(ll i)
{
ll ret=x[i]*aa[n-]%mod*bb[n-i]%mod;
ret=ret*b[tot-i+]%mod*a[tot-n-i+]%mod*a[n-]%mod;
return ret;
} inline ll gety(ll i)
{
ll ret=y[i]*bb[n-]%mod*aa[n-i]%mod;
ret=ret*b[tot-i+]%mod*a[tot-n-i+]%mod*a[n-]%mod;
return ret;
} int main()
{
n=read(); A=read(), B=read();
ready();
for(ll i=; i<=n; ++i) x[i]=read();
for(ll i=; i<=n; ++i) y[i]=read();
for(ll i=; i<=n; ++i) {
ans=(ans+getx(i))%mod;
}
for(ll i=; i<=n; ++i) {
ans=(ans+gety(i))%mod;
}
printf("%lld\n",ans);
return ;
}