SPOJ 19996 MOON1

来源:互联网 发布:软件开发工作量评估 编辑:程序博客网 时间:2024/06/05 05:02

Description
这里写图片描述
Input
第一行一整数T表示用例组数,每组用例输入三个整数n,a,r
1 < T
1 < r
1 < N < 10^9
1 < a < 10^9
(T < 1000 and r < 18 ) or (T < 100 and r < 72) or (T < 10 and r < 256) or (T = 1 and r < 444)
Output
对于每组用例,输出结果模1e9+7
Sample Input
2
3 4 5
6 7 8
Sample Output
16068
329990641
Solution
这里写图片描述
Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define mod 1000000007ll#define maxn 555ll C[maxn][maxn],A[maxn][maxn],B[maxn][maxn],D[maxn][maxn];int main(){    C[0][0]=1;    for(int i=1;i<=444;i++)    {        C[i][0]=C[i][i]=1;        for(int j=1;j<i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;    }    int T,n,a,r;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&n,&a,&r);        memset(A,0,sizeof(A));        for(int i=0;i<=r;i++)        {            for(int j=0;j<=i;j++)A[i][j]=1ll*a*C[i][j]%mod;            A[i][r+1]=1;         }        A[r+1][r+1]=1;        memset(B,0,sizeof(B));        for(int i=0;i<=r+1;i++)B[i][i]=1;        n--;        while(n)        {            if(n&1)            {                memset(D,0,sizeof(D));                for(int i=0;i<=r+1;i++)                    for(int k=0;k<=r+1;k++)                        if(B[i][k])                            for(int j=0;j<=r+1;j++)                                D[i][j]=(D[i][j]+B[i][k]*A[k][j]%mod)%mod;                for(int i=0;i<=r+1;i++)                    for(int j=0;j<=r+1;j++)                        B[i][j]=D[i][j];            }            memset(D,0,sizeof(D));            for(int i=0;i<=r+1;i++)                for(int k=0;k<=r+1;k++)                    if(A[i][k])                        for(int j=0;j<=r+1;j++)                            D[i][j]=(D[i][j]+A[i][k]*A[k][j]%mod)%mod;            for(int i=0;i<=r+1;i++)                for(int j=0;j<=r+1;j++)                    A[i][j]=D[i][j];            n>>=1;        }        ll ans=0;        for(int i=0;i<=r+1;i++)ans=(ans+1ll*a*B[r][i]%mod)%mod;        printf("%lld\n",ans);    }    return 0;}
0 0