hdu4686 Arc of Dream ——构造矩阵+快速幂

August 20, 2013

link: http://acm.hdu.edu.cn/showproblem.php?pid=4686

构造出来的矩阵是这样的:根据题目的ai * bi = ……,可以发现 矩阵1 * 矩阵3 = 矩阵2。然后就是矩阵快速幂了。

1

1	ai	bi	ai*bi	Si
0	0	0	0	0
0	0	0	0	0
0	0	0	0	0
0	0	0	0	0

2

1	ai+1	bi+1	ai+1*bi+1	Si+1
0	0	0	0	0
0	0	0	0	0
0	0	0	0	0
0	0	0	0	0

3

1	AY	BY	AY*BY	AY*BY
0	AX	0	AX*BY	AX*BY
0	0	BX	AY*BX	AY*BX
0	0	0	AX*BX	AX*BX
0	0	0	0	1
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <queue>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <functional>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <cassert>
#include <ctime>
#include <iterator>
const int INF = 0x3f3f3f3f;
const int dir[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
using namespace std;
#define LL __int64
#define MOD 1000000007
typedef struct
{
    LL m[5][5];
}mat;
mat X, Y;
LL n, a0, ax, ay, b0, bx, by;
mat multi(mat a, mat b)
{
    mat c; int j, i, k;
    for (i = 0; i < 5; ++i)
    {
        for (j = 0; j < 5; ++j)
        {
            c.m[i][j] = 0;
            for (k = 0; k < 5; ++k)
            {
                c.m[i][j] += a.m[i][k] * b.m[k][j]%MOD;
            }
            c.m[i][j] %= MOD;
        }
    }
    return c;
}
mat power(LL k)
{
    mat ans = X, p = Y;
    while (k)
    {
        if(k&1) ans = multi(ans, p);
        k /= 2; p = multi(p, p);
    }
    return ans;
}
int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin );
    #endif // ONLINE_JUDGE
    ios::sync_with_stdio(false);
    while (cin>>n>>a0>>ax>>ay>>b0>>bx>>by)
    {
        if(!n) {cout<<"0"<<endl; continue;}
        memset(X.m, 0, sizeof(X.m));
        memset(Y.m, 0, sizeof(Y.m));
        X.m[0][0] = 1, X.m[0][1] = a0%MOD, X.m[0][2] = b0%MOD,
        X.m[0][3] = a0*b0%MOD, X.m[0][4] = a0*b0%MOD;
        Y.m[0][0] = 1, Y.m[0][1] = ay%MOD, Y.m[0][2] = by%MOD,
        Y.m[0][3] = ay*by%MOD, Y.m[0][4] = ay*by%MOD, Y.m[1][1] = ax%MOD,
        Y.m[1][3] = ax*by%MOD, Y.m[1][4] = ax*by%MOD, Y.m[2][2] = bx%MOD,
        Y.m[2][3] = ay*bx%MOD, Y.m[2][4] = ay*bx%MOD, Y.m[3][3] = ax*bx%MOD,
        Y.m[3][4] = ax*bx%MOD, Y.m[4][4] = 1;
        mat ans = power(n-1);
        LL touch = ans.m[0][4];
        cout << touch <<endl;
    }
    return 0;
}

注意 n==0 的时候特判呐~

走吧,小胖!

comments powered by Disqus