【NOIP2016提高A组模拟8.17】Matrix

题目

【NOIP2016提高A组模拟8.17】Matrix_第1张图片
Input

【NOIP2016提高A组模拟8.17】Matrix_第2张图片
Sample Input

4 3 5
4 1 7 3
4 7 4 8

Output
这里写图片描述
Sample Output

59716

Data Constraint
【NOIP2016提高A组模拟8.17】Matrix_第3张图片

题目大意

现在有一个 nn 的矩形,我们现在已经知道了第一行和第一列的数,而矩阵中除了第一行和第一列的每一个数都满足 f[i,j]=af[i,j1]+bf[i1,j] 要求出 f[n,n] 的值

比赛时の想法

大概都想到了,对于一个在第一行第一列的数,它对答案的贡献可以表现成 paxby 的形式,其中x和y都很好推出来,p则表示在当前位置走到终点位置,每次只能向下或向右走一步的方案数,然后我推了N久愣是没有退出来,然后就GG了(:зゝ∠)_

正解

正难则反,我们可以从终点开始,退出每一个位置的贡献,我们设终点为1,然后每次向上走一步就乘b,向右走就乘a,然后很快就可以退出 33,44 这样的小矩形了,然后我们可以发现,x和y分别等于 (x1,yi)(xi,y1) ,这显然取决于当前点在第一行还是在第一列,而前面的系数就等于 Cn22ni2 (Cnm=m!n!(mn)!) 于是这个单项式的系数也被我们求出来了,但是分子和分母可能很大,并且我们知道不能直接把这两个数对1e9+7取模,所以我们可以用费马小定理,即:在a,b互质时a对于b的逆元= ab2 那么我们就快速幂一下,求出分子对于1e9+7的逆元,然后直接乘分母就可以啦QAQ

贴代码

const
    md=1000000007;
var
    l,t:array[0..100005]of int64;
    sum:array[0..200005]of int64;
    i,j,k,n:longint;
    ans,a,b,p,p1,x,y,x1:int64;
function quickmi(x,y:int64):int64;
var
    p,xx:int64;
begin
    p:=x;
    xx:=1;
    while y>0 do
    begin
        if y mod 2=1 then xx:=(xx*p) mod md;
        y:=y div 2;
        p:=(p*p) mod md;
    end;
    exit(xx);
end;
begin
    //assign(input,'t1.in'); reset(input);
    readln(n,a,b);
    for i:=1 to n do read(l[i]);
    readln;
    for i:=1 to n do read(t[i]);
    readln;
    sum[0]:=1;
    sum[1]:=1;
    for i:=2 to 2*n do sum[i]:=(sum[i-1]*i) mod md;
    x:=a;
    for i:=1 to n-2 do x:=(x*a) mod md;
    y:=1;
    for i:=n downto 2 do
    begin
        p:=sum[n-2]*sum[n-i];
        x1:=quickmi(p mod md,md-2);
        p1:=sum[2*n-i-2];
        p1:=(p1*x1) mod md;
        p:=p1;
        ans:=(ans+((p*x) mod md*y) mod md*l[i]) mod md;
        y:=(y*b) mod md;
    end;
    x:=b;
    for i:=1 to n-2 do x:=(x*b) mod md;
    y:=1;
    for i:=n downto 2 do
    begin
        p:=(sum[n-2]*sum[n-i]) mod md;
        x1:=quickmi(p mod md,md-2);
        p1:=sum[2*n-i-2];
        p1:=(p1*x1) mod md;
        p:=p1;
        ans:=(ans+((p*x) mod md*y) mod md*t[i]) mod md;
        y:=(y*a) mod md;
    end;
    if n=1 then ans:=l[1];
    writeln(ans);
    //close(input);
end.

你可能感兴趣的:(数学)