HDU 4686 Arc of Dream (2013多校聯合9 1001)

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


Problem Description
An Arc of Dream is a curve defined by following function:

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?
 

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 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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章