矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

题目链接

题意:

  

思路:

  直接拿别人的图,自己写太麻烦了~

  

  然后就可以用矩阵快速幂套模板求递推式啦~

另外:

  这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Google Codejam Round 1A的C题

#include <bits/stdc++.h>

typedef long long ll;
const int N = 5;
int a, b, n, mod;
/*
	*矩阵快速幂处理线性递推关系f(n)=a1f(n-1)+a2f(n-2)+...+adf(n-d)
*/
struct Matrix {
    int row, col;
    ll arr[N][N];
    Matrix(int r=0, int c=0) {
        row = r; col = c;
        memset (arr, 0, sizeof (arr));
    }
    Matrix operator * (const Matrix &B) {
        Matrix ret(row, B.col);
        for (int i=0; i<row; ++i) {
            for (int j=0; j<B.col; ++j) {
                for (int k=0; k<col; ++k) {
                    ret.arr[i][j] = (ret.arr[i][j] + (ll) arr[i][k] * B.arr[k][j]) % mod;
                }
            }
        }
        return ret;
    }
    void unit(int n) {
        row = col = n;
        for (int i=0; i<n; ++i) {
            arr[i][i] = 1;
        }
    }
};
Matrix operator ^ (Matrix X, ll n) {
    Matrix ret; ret.unit (X.col);
    while (n) {
        if (n & 1) {
            ret = ret * X;
        }
        X = X * X;
        n >>= 1;
    }
    return ret;
}

int f[3], x[3];

int main() {
    while (scanf ("%d%d%d%d", &a, &b, &n, &mod) == 4) {
        double c = (double) a + sqrt ((double) b);
        f[1] = ((ll) ceil (c)) % mod;
        f[2] = ((ll) ceil (c*c)) % mod;
        int d = 2;
        x[1] = (2*a) % mod; x[2] = (-(a*a-b) % mod + mod) % mod;

        if (n <= d) {
            printf ("%d\n", f[n]);
        } else {
            Matrix Fn(d+1, d+1), Fd(d+1, 1);
            for (int i=0; i<Fn.row-1; ++i) {
                Fn.arr[i][i+1] = 1;
            }
            for (int i=1; i<Fn.col; ++i) {
                Fn.arr[Fn.row-1][i] = x[d-i+1];
            }
            for (int i=0; i<Fd.row; ++i) {
                Fd.arr[i][0] = f[i];
            }
            Fn = Fn ^ (n - d);
            Fn = Fn * Fd;
            printf ("%d\n", Fn.arr[d][0]);
        }
    }
    return 0;
}

  

时间: 2025-01-05 18:56:57

矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)的相关文章

矩阵快速幂——HDU 2604

对应HDU题目:点击打开链接 Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3114    Accepted Submission(s): 1419 Problem Description Queues and Priority Queues are data structures which are known t

递推+矩阵快速幂 HDU 2065

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace std; 6 7 //矩阵大小上限 8 const int SIZ=100; 9 int MOD=100; 10 11 //矩阵大小为n*m,初始化全部为0 12 struct mat 13 { 14 int n,m; 15 int ar[SIZ][SIZ]; 16 mat() 17 { 18 memset

[矩阵快速幂] hdu 5015 233 Matrix

之前各种犯傻 推了好久这个东西.. 后来灵关一闪  就搞定了.. 矩阵的题目,就是构造矩阵比较难想! 题意:给出一个矩阵的第一列和第一行(下标从0开始),(0,0)位置为0, 第一行为,233,2333,23333...一次加个3, 第一列为输入的n个数. 然后从(1,1)位置开始,等于上面的数加左边的数,问(n+1,m+1)的数是多少,也就是右下角的数 思路: 把矩阵画出来: |   0     233   2333  | |  b0     b1     b2     | |  c0    

矩阵快速幂 [HDU 4549] M斐波那契数列

M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1609    Accepted Submission(s): 460 Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a,

[矩阵快速幂] hdu 3936 FIB Query

题意: 求定义y(x)=4*x-1 给L.R求 fib(y(L))~fib(y(R))的和 思路: 和之前做的一道题类似. 定于Fib为 1 1 1 0 我们的第一项就是x=1时的 就是Fib^3 然后下一项其实就是fib(3+4)=Fib^3*Fib^4 所以递推矩阵就是Fib^4 然后求和利用快速的求法 设 Fib E 0    E 这样运算N次右上角的矩阵就是我们要的和的矩阵了 然后就是答案了~! 代码: #include"cstdlib" #include"cstdi

【矩阵快速幂】HDU4565 So Easy!

题意:给a, b, n, m 求 $\left \lceil ( a+ \sqrt b )^n \right \rceil$ % m 看到 $( a+ \sqrt b )^n$ 虽然很好联想到共轭 但是推出矩阵还是比较难的 数据范围为:$(a-1)^2 < b < a^2$ 那么  $a-1 < sqrt b < a$ 那么          $0 < a-sqrt b < 1$

[矩阵快速幂] hdu 3893 Drawing Pictures

题意: 给长度N的格子,有六种颜料ABCDEF, 要求涂满N个格子的方案数,并且保证是对称的,并且相邻的格子颜色不同,并且不出现ABCDEF这个序列. 思路: 受到中午那题,思维大开 首先因为颜色相邻不能相同且要对称,所以N为偶数答案为0. 接着先假设有这六种状态0(代表没颜色限制),A,AB,ABC,ABCD,ABCDE 然后初始状态为(5,1,0,0,0,0)两两之间构成转换关系 结果提交WA了 发现这题真是丧心病狂 如果是这样FEDCBABCDEF 这样对称的话就会跪 所以还有5个状态 F

[矩阵快速幂] hdu 4990 Reading comprehension

题意: 初始值为零,后面奇数项成二加一,偶数项乘二. 思路: 其实区别就在于这个加一. 就是构造一个-1每次相成,然后1-1+1就ok了. 就是 |  -1   1   0  | | -1  1  0 | * |   0   1   1  |  =  | 1  0  1 | |   0   0   2  | 依次类推就好了. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #inc

hdu 4565 So Easy! (共轭构造+矩阵快速幂)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4565 题目大意: 给出a,b,n,m,求出的值, 解题思路: 因为题目中出现了开根号,和向上取整后求余,所以用矩阵快速幂加速求解过程的时候,会产生误差,就很自然地想到了凑数,因为(a-1)^2<b<a^2,得出0<a-sqrt(b)<1,则无论n取多大,(a-sqrt(b))^n都是小于1的,(a-sqrt(b))^n 与 (a+sqrt(b))^n共轭,两者展开后会相互抵销,所以(