Matrix

Description

Matrix_第1张图片

Data Constraint

Matrix_第2张图片

Solution

这道题看范围显然是要O(n log n)才能过,那么怎么直接算F[n][n]而不是一个个推下去呢,我们可以分开考虑第一列和第一行每个数对F[n][n]的贡献。而对于F[1][i]的贡献就是从它到F[n][n]的所有路径,每向右就乘a,向下就乘b。所以贡献=路径数 * [a^(n-i)] * [b^(n-1)] * F[1][i],对于F[i][1]也类似。只要O(n)预处理出a和b的幂就好了。
那么该怎么快速的求路径数呢。小学就做过的题…递推式就是g[i][j]=g[i-1][j]+g[i][j-1],但这是O(n^2)的。但仔细一看,这不就是杨辉三角么。据杨辉三角通项公式就可以得到路径数= Cnin2i2 ,然后问题解决了。

*注意:n=1要特判。

Code

Const
    Maxn=200005;
    Mo=1000000007;

Var
    n,a,b,Ans:Int64;
    Pow:Array[0..Maxn] OF Record
                              a,b:Int64;
                          End;
    l,t,Fac:Array[0..Maxn] OF Int64;

Procedure Init();
Var
    i:Longint;
Begin
    Readln(n,a,b);
    For i:=1 To n Do Read(l[i]);
    For i:=1 To n Do Read(t[i]);
End;

Procedure Pre();
Var
    i:Longint;
Begin
    Fac[0]:=1;
    Pow[0].a:=1; Pow[0].b:=1;
    For i:=1 To n*2 Do
    Begin
        Fac[i]:=(Fac[i-1]*i) Mod Mo;
        Pow[i].a:=(Pow[i-1].a*a) Mod Mo;
        Pow[i].b:=(Pow[i-1].b*b) Mod Mo;
    End;
End;

Function Count(x,y:Int64):Int64;
Begin
    Count:=1;
    x:=x Mod Mo;
    While y>0 Do
    Begin
        If Odd(y) Then Count:=(Count*x) Mod Mo;
        x:=(x*x) Mod Mo; y:=y >> 1;
    End;
End;

Function C(x,y:Longint):Int64;
Begin
    C:=(Fac[y]*Count(Fac[x]*Fac[y-x],Mo-2)) Mod Mo;
End;

Procedure Work();
Var
    i:Longint;
    k1,k2:Int64;
Begin
    For i:=2 To n Do
    Begin
        k1:=((Pow[n-i].a*Pow[n-1].b) Mod Mo*t[i]) Mod Mo;
        k2:=((Pow[n-1].a*Pow[n-i].b) Mod Mo*l[i]) Mod Mo;
        Ans:=(Ans+(k1+k2)*C(n-i,n*2-i-2)) Mod Mo;
    End;
    If n=1 Then Ans:=l[1];
End;

Begin
    //Assign(Input,'Matrix.in'); Reset(Input);
    //Assign(Output,'Matrix.out'); Rewrite(Output);

    Init();
    Pre();
    Work();
    Writeln(Ans);

    //Close(Input); Close(Output);
End.

你可能感兴趣的:(combinator)