zoukankan      html  css  js  c++  java
  • [WikiOI "天梯"1281] Xn数列

    题目描述Description

    给你6个数,m, a, c, x0, n, g

    Xn+1 = ( aXn + c ) mod m,求Xn

    m, a, c, x0, n, g<=10^18

    输入描述Input Description

    一行六个数 m, a, c, x0, n, g

    输出描述Output Description

    输出一个数 Xn mod g

    样例输入Sample Input

    11 8 7 1 5 3

    样例输出Sample Output

    2

    数据范围及提示Data Size & Hint

    int64按位相乘可以不要用高精度。

    题目分析
            典型的矩阵快速幂问题。由递推式 Xn+1 = ( aXn + c ) mod m 可以构造出矩阵方程
                                       

           那么题目所求就可转化为一个1*2矩阵与n个二阶方阵的矩阵链乘。根据矩阵乘法的结合律,可得出:

                                      
        即可转化为矩阵快速幂问题。其中的乘法运算已改为了倍增取模乘法。
     
     1 //WikiOI 1281 Xn数列
     2 #include <iostream>
     3 using namespace std;
     4 typedef long long LL;
     5 LL m, a, c, x0, n, MOD;
     6 LL mlti(LL a, LL b) //倍增取模乘法
     7 {
     8     a %= m;
     9     LL ans = 0;
    10     while(b)
    11     {
    12         if(b & 1)ans = (ans + a)% m;
    13         a = (a << 1)% m;
    14         b >>= 1;
    15     }
    16     return ans;
    17 }
    18 struct Matrix2
    19 {
    20     LL val[2][2];
    21     Matrix2(LL k1,LL k2,LL k3,LL k4)
    22     {
    23         val[0][0] = k1; val[0][1] = k2; val[1][0] = k3; val[1][1] = k4;
    24     }
    25     void Mlti(Matrix2 &m) //矩阵乘法
    26     {
    27         LL v1 = mlti(val[0][0],m.val[0][0])+mlti(val[0][1],m.val[1][0]);
    28         LL v2 = mlti(val[0][0],m.val[0][1])+mlti(val[0][1],m.val[1][1]);
    29         LL v3 = mlti(val[1][0],m.val[0][0])+mlti(val[1][1],m.val[1][0]);
    30         LL v4 = mlti(val[1][0],m.val[0][1])+mlti(val[1][1],m.val[1][1]);
    31         val[0][0] = v1,val[0][1] = v2,val[1][0] = v3,val[1][1] = v4;
    32     }
    33 };
    34 
    35 int main()
    36 {
    37     ios::sync_with_stdio(0); //感谢陈思学长!
    38     cin >>m >>a >>c >>x0 >>n >>MOD;
    39     Matrix2 M(a, 011);
    40     Matrix2 ans = M;
    41     n -= 1;
    42     while(n)
    43     {
    44         if(n & 1) ans.Mlti(M);
    45         M.Mlti(M);
    46         n >>=1;
    47     }
    48     cout << ((mlti(x0, ans.val[0][0])+mlti(c, ans.val[1][0]))%m)%MOD;
    49     return 0;
    50 }

  • 相关阅读:
    基于Python的人脸动漫转换
    let 与 var的区别
    【LeetCode】汇总
    【HDU】4632 Palindrome subsequence(回文子串的个数)
    【算法】均匀的生成圆内的随机点
    【LeetCode】725. Split Linked List in Parts
    【LeetCode】445. Add Two Numbers II
    【LeetCode】437. Path Sum III
    【LeetCode】222. Count Complete Tree Nodes
    【LeetCode】124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/Asm-Definer/p/3764574.html
Copyright © 2011-2022 走看看