Calculation

来源:互联网 发布:Windows支持的文件系统 编辑:程序博客网 时间:2024/05/16 11:30

题目描述

定义下列函数:
题目描述

其中:
题目描述

给出了A0、AX、AY、B0、BX、BY。计算S(N)

输入

多组输入,每组输入包括三行。
第一行一个正整数N(1<=N<=1018)
第二行和第三行各包含三个非负整数:

A0 AX AY
B0 BX BY

其中A0,AX,AY,B0,BX,BY均不大于2x109

输出

输出S(N),对1000000007取模

样例输入

1
1 2 3
4 5 6

样例输出

130

#include <iostream>#include<string.h>using namespace std;#define M 1000000007#define LL long longstruct Matrix{    LL a[6][6];}origin,res,tmp,A,ans;int n = 5;Matrix mul(Matrix x,Matrix y){    int i,j,k;    memset(tmp.a,0,sizeof(tmp.a));    for(i=1;i<=n;i++)        for(j=1;j<=n;j++)            for(k=1;k<=n;k++)            {                tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%M;                tmp.a[i][j]%=M;            }    return tmp;}void quickpow(LL k){    int i;    memset(res.a,0,sizeof(res.a));    for(i=1;i<=n;i++)        res.a[i][i]=1;    while(k)    {        if(k&1)            res=mul(res,A);        A=mul(A,A);        k>>=1;    }}int main(){    LL a0, ax, ay, b0, bx, by, N;    LL f1,a1,b1,s0;    while(cin >> N) {        cin >> a0 >> ax >> ay;        cin >> b0 >> bx >> by;        a1=(a0*ax+ay)%M;        b1=(b0*bx+by)%M;        f1=(a1*b1)%M;        s0=0;        memset(origin.a,0,sizeof(origin.a));        origin.a[1][1]=f1;        origin.a[1][2]=a1;        origin.a[1][3]=b1;        origin.a[1][4]=1;        origin.a[1][5]=s0;        memset(A.a,0,sizeof(A.a));        A.a[1][1]=(ax*bx)%M;        A.a[1][5]=1;        A.a[2][1]=(ax*by)%M;        A.a[2][2]=ax%M;        A.a[3][1]=(ay*bx)%M;        A.a[3][3]=bx%M;        A.a[4][1]=(ay*by)%M;        A.a[4][2]=ay%M;        A.a[4][3]=by%M;        A.a[4][4]=1;        A.a[5][5]=1;        quickpow(N);        ans=mul(origin,res);        printf("%lld\n",ans.a[1][5]);    }    return 0;}
    这道题单纯从逻辑上讲是很简单的,貌似一下就写出来了,但是仔细一看,这里的N是大的可怕,正常做法绝对会超时(自己试一下就知道好慢的说)。网上看到大神是将递归归纳成矩阵快速幂,然后这样就不用一个一个执行了。(发现这个方法真的很好用,很多地方都用得到!)

下面是具体思路参考的博客,很清楚。
http://www.cnblogs.com/frog112111/archive/2013/08/21/3273660.html

0 0