http://acm.hdu.edu.cn/showproblem.php?pid=4686
Arc of Dream
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 287 Accepted Submission(s): 88
where
a0 = A0
ai = ai-1*AX+AY
b0 = B0
bi = bi-1*BX+BY
What is the value of AoD(N) modulo 1,000,000,007?
Each test case contains 7 nonnegative integers as follows:
N
A0 AX AY
B0 BX BY
N is no more than 1018, and all the other integers are no more than 2×109.
思路:很明顯且基礎的矩陣乘法題,我們構造這樣一個矩陣(5*5)
那麼 下面這個1*5的矩陣
與上面所構造的矩陣相乘後的結果即爲
那麼我們要求AoD(n)用常規的矩陣加速乘法即可解決,複雜度爲O(5*5*5*log(n))
下面是代碼 :
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define mod 1000000007
#define LL long long
using namespace std;
LL c[70][6][6];
LL ans[6][6];
int m=5;
void init(LL a[6][6],LL b[6][6], LL c[6][6])
{
int i,j,k;
LL tmp[6][6];
memset(tmp,0,sizeof(tmp));
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
{
for(k=1;k<=m;k++)
{
tmp[i][j]+=b[i][k]*c[k][j];
tmp[i][j]%=mod;
}
}
}
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
a[i][j]=tmp[i][j];
}
}
void build(int num)
{
if(num==1)
return;
build(num-1);
init(c[num],c[num-1],c[num-1]);
}
LL tt[6];
void solve(LL n)
{
if(n==0)
{
printf("0\n");
return;
}
memset(ans,0,sizeof(ans));
int t[70],num=0;
while(n)
{
t[++num]=n%2;
n/=2;
}
build(num);
int i,j;
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
ans[i][j]=c[num][i][j];
}
for(i=1;i<num;i++)
{
if(t[i])
{
init(ans,ans,c[i]);
}
}
LL sum=0;
for(i=1;i<=m;i++)
{
sum=(sum+ans[i][1]*tt[i])%mod;
}
printf("%I64d\n",sum);
}
int main()
{
freopen("dd.txt","r",stdin);
LL a0,b0,ax,ay,bx,by,n;
while(scanf("%I64d",&n)!=EOF)
{
scanf("%I64d%I64d%I64d",&a0,&ax,&ay);
scanf("%I64d%I64d%I64d",&b0,&bx,&by);
tt[1]=0,tt[2]=a0,tt[3]=b0,tt[4]=a0*b0%mod,tt[5]=1;
memset(c,0,sizeof(c));
c[1][1][1]=c[1][4][1]=c[1][5][5]=1;
c[1][2][2]=ax;
c[1][5][2]=ay;
c[1][3][3]=bx;
c[1][5][3]=by;
c[1][2][4]=ax*by%mod;c[1][3][4]=bx*ay%mod;c[1][4][4]=ax*bx%mod,c[1][5][4]=ay*by%mod;
solve(n);
}
return 0;
}