zoukankan      html  css  js  c++  java
  • 矩阵快速幂 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
    ", 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
    ", Fn.arr[d][0]);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    ubuntu开启SSH服务
    Ubuntu修改虚拟内存(即swap空间)
    【转】Ubuntu 13.10中MyEclipse 10.6+下载+安装+破解
    【转】 ubuntu下安装mysql
    【转】 Ubuntu 11.04 下安装配置 JDK 7
    Linux非root用户安装jdk和tomcat
    algorithm之改变序列算法--待解决
    时间日期设置--ctime头文件
    C中的一些函数
    algorithm之不变序列操作
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5659514.html
Copyright © 2011-2022 走看看