HDU 4686解題報告

Arc of Dream

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2452    Accepted Submission(s): 753


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.
 

Output
For each test case, output AoD(N) modulo 1,000,000,007.
 

Sample Input
1 1 2 3 4 5 6 2 1 2 3 4 5 6 3 1 2 3 4 5 6
 

Sample Output
4 134 1902
 

Author
Zejun Wu (watashi)
 

Source
 

Recommend
zhuyuanchen520   |   We have carefully selected several similar problems for you:  5177 5176 5175 5174 5173 

       這道題是比較難的矩陣構造題。不過通過之前做的那幾道和本題相似的矩陣題。我們也可以掌握一定的矩陣構造技巧。因而構造出合適的矩陣還是很容易的。

       

        參考代碼:(利用分塊矩陣求解,當然也可以用二分矩陣多項式+矩陣快速冪)

代碼略醜,用的時間也稍微長一些。       

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<ctime>
#include<cstdlib>
#include<iomanip>
#include<utility>
#define pb push_back
#define mp make_pair
#define CLR(x) memset(x,0,sizeof(x))
#define _CLR(x) memset(x,-1,sizeof(x))
#define REP(i,n) for(int i=0;i<n;i++)
#define Debug(x) cout<<#x<<"="<<x<<" "<<endl
#define REP(i,l,r) for(int i=l;i<=r;i++)
#define rep(i,l,r) for(int i=l;i<r;i++)
#define RREP(i,l,r) for(int i=l;i>=r;i--)
#define rrep(i,l,r) for(int i=1;i>r;i--)
#define read(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<11
using namespace std;
const int MOD=1000000000+7;
ll n,a0,ax,ay,b0,bx,by;
struct mat
{
    ll d[4][4];
}A,B,E1;

struct Mat
{
    mat m[2][2];
}M,E;

mat multi(mat a,mat b)
{
    mat ans;
    rep(i,0,4)
    {
        rep(j,0,4)
        {
            ans.d[i][j]=0;
            rep(k,0,4)
                if(a.d[i][k]&&b.d[k][j])
                    ans.d[i][j]+=a.d[i][k]*b.d[k][j];
            if(ans.d[i][j]>=MOD)
                ans.d[i][j]%=MOD;
        }
    }
    return ans;
}

mat add(mat a,mat b)
{
    mat ans;
    rep(i,0,4)
    {
        rep(j,0,4)
        {
            ans.d[i][j]=a.d[i][j]+b.d[i][j];
            if(ans.d[i][j]>=MOD)
                ans.d[i][j]%=MOD;
        }
    }
    return ans;
}

Mat Multi(Mat a,Mat b)
{
    Mat ans;
    CLR(ans.m);
    rep(i,0,2)
        rep(j,0,2)
            rep(k,0,2)
                ans.m[i][j]=add(ans.m[i][j],multi(a.m[i][k],b.m[k][j]));
    return ans;
}

mat quickmulti(Mat a,ll n)
{
    if(n==0) return E.m[0][1];
    if(n==1) return a.m[0][1];
    Mat ans=E;
    while(n)
    {
        if(n&1)
        {
            n--;
            ans=Multi(ans,a);
        }
        else
        {
            n>>=1;
            a=Multi(a,a);
        }
    }
    return ans.m[0][1];
}

int main()
{
    CLR(E1.d);CLR(E.m);
    rep(i,0,4)
       E1.d[i][i]=1;
    rep(i,0,2)
      rep(j,0,4)
         E.m[i][i].d[j][j]=1;
    while(~scanf("%I64d",&n))
    {
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a0,&ax,&ay,&b0,&bx,&by);
        if(n==0)
        {
            printf("0\n");
            continue;
        }
        A.d[0][0]=ax*bx%MOD;A.d[0][1]=ax*by%MOD;A.d[0][2]=ay*bx%MOD;A.d[0][3]=ay*by%MOD;
        A.d[1][0]=0;A.d[1][1]=ax%MOD;A.d[1][2]=0;A.d[1][3]=ay%MOD;
        A.d[2][0]=0;A.d[2][1]=0;A.d[2][2]=bx%MOD;A.d[2][3]=by%MOD;
        A.d[3][0]=0;A.d[3][1]=0;A.d[3][2]=0;A.d[3][3]=1;
        CLR(B.d);
        B.d[0][0]=a0*b0%MOD;B.d[1][0]=a0%MOD;B.d[2][0]=b0%MOD;B.d[3][0]=1;
        Mat M;
        CLR(M.m);
        M.m[0][0]=E1;M.m[0][1]=M.m[1][1]=A;
        mat ans=quickmulti(M,n-1);
        ans=add(ans,E1);
        ans=multi(ans,B);
        printf("%I64d\n",ans.d[0][0]);
    }
}
發佈了69 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章