• Reading comprehension HDU


    原题链接

    • 题意:多组输入,输入 (1 <= n ,m <=1000000000)(ans=0) ,当 (ans) 为偶数, (ans = ans imes 2 + 1),如果 (ans) 为奇数,那么 (ans = ans imes 2)。输出 (ans)

    • 题解:可以发现,答案要么是 (2 imes ans) ,即只有系数起作用,要么是 (2 imes ans + 1) ,即有一个 (1) 起作用,那么就可以构造 (ANS) 矩阵了。
      (egin{bmatrix}ans&0\1&0end{bmatrix}) 然后发现其实,系数矩阵有两个,但是这两个的(a_{1,1})一定是 (2),然后为了维护 (ANS) 矩阵的 (a_{2,1}=1),所有的系数矩阵(a_{2,2} = 1),很容易得算出,如果要对 (ans) 乘二加一,显然系数矩阵的 (a_{1, 2} = 1) 否则 (a_{1, 2} = 0),然后得到两个系数矩阵 (A = egin{bmatrix}2&1\0&1end{bmatrix}, B = egin{bmatrix}2&0\0&1end{bmatrix}) 同时那么知道了系数矩阵,所以就可以用快速幂加速了,尽管有两个稀疏矩阵,其实发现他们相乘的数量都是 (left lfloor frac{n}{2} ight floor),就是 (A) 矩阵, 如果 (n%2 = 1) 的话 (A) 矩阵还要再左乘一下。

    • 代码:

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    
    typedef long long ll;
    const int N = 1e3  + 9;
    ll mod = 6;
    ll n, m;
    struct Matrix {
        ll a[10][10];
        Matrix(){memset(a, 0, sizeof a);}
        Matrix operator*(Matrix rhs)const {
            Matrix ret;
            for (int i = 0; i < 2; i ++) {
                for (int j = 0; j < 2; j++){
                    for (int k = 0; k < 2; k++) {
                        (ret.a[i][j] += (a[i][k] * rhs.a[k][j] % mod)) %= mod;
                    }
                }
            }
            return ret;
        }
        void pr() {
            for (int i = 0; i < 2; i ++) {
                for (int j = 0; j < 2; j++){
                    cout << a[i][j] << " ";
                }
                cout << endl;
            }
        }
    };
    Matrix ksm (Matrix A, int kk) {
        if (kk == 1)return A;
        Matrix ret;
        bool f = 0;
        while (kk) {
            if (kk & 1) {
                if (!f) {
                    ret = A;
                    f = 1;
                } else
                ret = ret * A;
            }
            kk >>= 1;
            A = A * A;
        }
        return ret;
    }
    void solve() {
        ll a[2][2] = 
        {  
            {2, 1}, 
            {0, 1} 
        };
        ll b[2][2] = 
        {
            {2, 0},
            {0, 1}
        };
    n = 0;
    while (cin >> n >> m) {
        mod = m;
        Matrix A, B;
        for (int i = 0; i  < 2; i++) {
            for (int j = 0; j < 2; j++) {
                A.a[i][j] = a[i][j];
                B.a[i][j] = b[i][j];
            }
        }
        Matrix C = A*B;
        n--;
        ll k = n/2;
        Matrix ans;
        ans.a[1][0] = 1;
        ans.a[0][0] = 1;
        if (k != 0) {
            C = ksm(C, k);
            ans = C * ans;
        }
        if (n % 2) {
            ans = B * ans;
        }
        if (m == 1)cout << 0 << endl;
        else 
        cout << ans.a[0][0] << endl;
    }
    }
    signed main() {
        int t = 1;//cin >> t;
        while (t--) {
            solve();
        }
    }
    
    
  • 相关阅读:
    python实现双向链表
    django contenttypes
    tensorflow学习笔记一
    vue指令和事件绑定
    es6简单介绍
    mysql主从复制
    mysql事务
    winform 使用 ReportViewer做报表
    设置控件获取焦点
    修改安卓串口蓝牙app问题记录
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14584282.html
Copyright © 2020-2023  润新知