hdu 4686 Arc of Dream 自己推 矩阵快速幂

A.mat[0][0] = 1, A.mat[0][1] = 1, A.mat[0][2] = 0, A.mat[0][3] = 0, A.mat[0][4] = 0;
A.mat[1][0] = 0, A.mat[1][1] = AX*BX%Mod, A.mat[1][2] = AX*BY%Mod, A.mat[1][3] = AY*BX%Mod, A.mat[1][4] = AY*BY%Mod;
A.mat[2][0] = 0, A.mat[2][1] = 0, A.mat[2][2] = AX, A.mat[2][3] = 0, A.mat[2][4] = AY;
A.mat[3][0] = 0, A.mat[3][1] = 0, A.mat[3][2] = 0, A.mat[3][3] = BX, A.mat[3][4] = BY;
A.mat[4][0] = 0, A.mat[4][1] = 0, A.mat[4][2] = 0, A.mat[4][3] = 0, A.mat[4][4] = 1;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;
const ll Mod = 1e9 + 7;
const int N = 6;
int msize;

struct Mat
{
    ll mat[N][N];
};

Mat operator *(Mat a, Mat b)
{
    Mat c;
    memset(c.mat, 0, sizeof(c.mat));
    for(int k = 0; k < msize; ++k)
        for(int i = 0; i < msize; ++i)
            if(a.mat[i][k])
                for(int j = 0; j < msize; ++j)
                    if(b.mat[k][j])
                        c.mat[i][j] = (a.mat[i][k] * b.mat[k][j] + c.mat[i][j])%Mod;
    return c;
}

Mat operator ^(Mat a, ll k)
{
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i = 0; i < msize; ++i)
        c.mat[i][i]=1;
    for(; k; k >>= 1)
    {
        if(k&1) c = c*a;
        a = a*a;
    }
    return c;
}

int main()
{
    ll n,A0,B0,AX,AY,BX,BY;
    msize = 5;
    while(~scanf("%I64d",&n))
    {
        scanf("%I64d%I64d%I64d", &A0, &AX, &AY);
        scanf("%I64d%I64d%I64d", &B0, &BX, &BY);
        if(n==0)
        {
            puts("0");
            continue;
        }
        Mat A;
        A.mat[0][0] = 1, A.mat[0][1] = 1,         A.mat[0][2] = 0,         A.mat[0][3] = 0,         A.mat[0][4] = 0;
        A.mat[1][0] = 0, A.mat[1][1] = AX*BX%Mod, A.mat[1][2] = AX*BY%Mod, A.mat[1][3] = AY*BX%Mod, A.mat[1][4] = AY*BY%Mod;
        A.mat[2][0] = 0, A.mat[2][1] = 0,         A.mat[2][2] = AX,        A.mat[2][3] = 0,         A.mat[2][4] = AY;
        A.mat[3][0] = 0, A.mat[3][1] = 0,         A.mat[3][2] = 0,         A.mat[3][3] = BX,        A.mat[3][4] = BY;
        A.mat[4][0] = 0, A.mat[4][1] = 0,         A.mat[4][2] = 0,         A.mat[4][3] = 0,         A.mat[4][4] = 1;
        A = A^(n);
        ll AoD1 = A0*B0%Mod;
        printf("%I64d\n",(A.mat[0][1]*AoD1%Mod + A.mat[0][2]*A0%Mod + A.mat[0][3]*B0%Mod + A.mat[0][4])%Mod);
    }
    return 0;
}
时间: 2024-10-25 03:16:33

hdu 4686 Arc of Dream 自己推 矩阵快速幂的相关文章

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 140 Problem Description Farmer John likes to play mathematics games with his N cows. Recently, t

HDU 4686 Arc of Dream(快速幂矩阵)

题目链接 再水一发,构造啊,初始化啊...wa很多次啊.. #include <cstring> #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define MOD 1000000007 #define

hdu 2604 递推 矩阵快速幂

HDU 2604 Queuing (递推+矩阵快速幂) 这位作者讲的不错,可以看看他的 #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> using namespace std; const int N = 5; int msize, Mod; struct Mat { int mat[N][N]; }; M

2014 BNU 邀请赛E题(递推+矩阵快速幂)

Elegant String 题意:给定一个字符串,由0-k数字组成,要求该串中,子串不包含0-k全排列的方案数 思路:dp[i][j]表示放到i个数字,后面有j个不相同,然后想递推式,大概就是对应每种情况k分别能由那几种状态转移过来,在纸上画画就能构造出矩阵了,由于n很大,所以用快速幂解决 代码: #include <stdio.h> #include <string.h> const long long MOD = 20140518; int t; long long n; i

HDU 5171 GTY&#39;s birthday gift(矩阵快速幂 )

HDU 5171 GTY's birthday gift ( 矩阵快速幂裸题目 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 3 #define MOD 10000007 #define clr( a, b ) memset( a, b, sizeof(a) ) typedef long long LL; struct M

HDU 4686 Arc of Dream 矩阵快速幂,线性同余 难度:1

http://acm.hdu.edu.cn/showproblem.php?pid=4686 当看到n为小于64位整数的数字时,就应该有个感觉,acm范畴内这应该是道矩阵快速幂 Ai,Bi的递推式题目已经给出, Ai*Bi=Ax*Bx*(Ai-1*Bi-1)+Ax*By*Ai-1+Bx*Ay*Bi-1+Ay*By AoD(n)=AoD(n-1)+AiBi 构造向量I{AoD(i-1),Ai*Bi,Ai,Bi,1} 初始向量为I0={0,A0*B0,A0,B0,1} 构造矩阵A{ 1,0,0,0,

HDU 4686 Arc of Dream

矩阵快速幂 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct Matrix { long long A[10][10]; Matrix operator*(Matrix b); }; const long long MOD=1000000007; long long R,C; long long N,A0,AX,

HDU 2842 (递推+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2842 题目大意:棒子上套环.第i个环能拿下的条件是:第i-1个环在棒子上,前i-2个环不在棒子上.每个环可以取下或放上,cost=1.求最小cost.MOD 200907. 解题思路: 递推公式 题目意思非常无聊,感觉是YY的. 设$dp[i]$为取第i个环时的总cost. $dp[1]=1$,$dp[2]=2$,前两个环取下是没有条件要求的. 从i=3开始,由于条件对最后的环限制最大,所以从最后一

HDU 2604 Queuing (递推+矩阵快速幂)

[题目链接]:click here~~ [题目大意]: n个人排队,f表示女,m表示男,包含子串'fmf'和'fff'的序列为O队列,否则为E队列,有多少个序列为E队列. [思路]: 用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1): 如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff,其中fff和fmf不满足题意所以我们不考虑,但是如果是 mmf的话那么前n-3可以找满足