Arc of DreamTime Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3126 Accepted Submission(s): 982
Problem Description
An Arc of Dream is a curve defined by following function:
where a 0 = A0 a i = a i-1*AX+AY b 0 = B0 b i = b i-1*BX+BY What is the value of AoD(N) modulo 1,000,000,007?
Input
There are multiple test cases. Process to the End of File.
Each test case contains 7 nonnegative integers as follows: N A0 AX AY B0 BX BY N is no more than 10 18, and all the other integers are no more than 2×10 9.
Output
For each test case, output AoD(N) modulo 1,000,000,007.
Sample Input
Sample Output
Author
Zejun Wu (watashi)
Source
Recommend
zhuyuanchen520 | We have carefully selected several similar problems for you:
5390
5389
5388
5387
5386
|
题意:看公式就可以了。。。。ai*bi的数列前n项(0—n-1)求和。
解题思路:10^18次方。。果断利用矩阵快速幂。。关键是找出相乘的矩阵。
1 | 0 | 0 | 1 | 0 |
0 | Ax | 0 | 0 | Ay |
0 | 0 | Bx | 0 | By |
0 | Ax*By | Bx*Ay | Ax*Bx | Ay*By |
0 | 0 | 0 | 0 | 1 |
就是利用上述矩阵去乘以
Si-1 |
ai-1 |
bi-1 |
ai-1*bi-1 |
1 |
它们相乘的结果就是
Si |
ai |
bi |
ai*bi |
1 |
所以直接对第一个矩阵进行N阶快速幂。乘以第二个矩阵,得到最后一个矩阵,输出第一个元素即可。
AC代码:
#include <stdio.h>
#include <math.h>
#include <vector>
#include <queue>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 5;
const LL Modn = 1000000007;
LL res[MAXN][MAXN];
LL a[MAXN][MAXN];
LL A0,Ax,Ay,B0,Bx,By;
void Matmul(LL X[MAXN][MAXN],LL Y[MAXN][MAXN])
{
LL t[MAXN][MAXN]={0};
for(int i=0;i<MAXN;i++){
for(int k=0;k<MAXN;k++)
if(X[i][k])
for(int j=0;j<MAXN;j++)
t[i][j]=(t[i][j]+X[i][k]*Y[k][j]%Modn)%Modn;
}
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++)
X[i][j]=t[i][j];
}
void Matrix(LL X[MAXN][MAXN],LL n)
{
for(int i=0;i<MAXN;i++)
for(int j=0;j<MAXN;j++)
res[i][j]=(i==j);
while(n){
if(n&1) Matmul(res,X);
Matmul(X,X);
n>>=1;
}
}
void init()
{
memset(a,0,sizeof(a));
a[0][0]=a[0][3]=1;
a[1][1]=Ax%Modn;a[1][4]=Ay%Modn;
a[2][2]=Bx%Modn;a[2][4]=By%Modn;
a[3][1]=Ax*By%Modn;a[3][2]=Bx*Ay%Modn;
a[3][3]=Ax*Bx%Modn;a[3][4]=Ay*By%Modn;
a[4][4]=1;
}
int main()
{
LL N,S;
while(scanf("%lld",&N)!=EOF){
LL ans[5];
scanf("%lld%lld%lld%lld%lld%lld",&A0,&Ax,&Ay,&B0,&Bx,&By);
if(N==0){
printf("0\n");
continue;
}
ans[0]=0;ans[1]=A0;ans[2]=B0;ans[3]=A0*B0%Modn;ans[4]=1;
init();
Matrix(a,N);
S=0;
for(int i=0;i<MAXN;i++){
S=(S+ans[i]*res[0][i]%Modn)%Modn;
}
printf("%lld\n",S);
}
return 0;
}