您的位置:首页 > 编程语言 > C语言/C++

Calculation

2016-06-21 23:15 267 查看

题目描述

定义下列函数:



其中:



给出了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 long

struct 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 算法