zoukankan      html  css  js  c++  java
  • 【矩阵乘法+快速乘】BZOJ2875-[NOI2012]随机数生成器

    【题目大意】

     已知Xn+1=(aXn+c) mod m,求Xn mod g。

    【思路】

    get到了longlong乘法的正确方法,快速乘。什么是快速乘呢?

    简单来讲,快速幂就是模拟了二进制的竖式乘法。如:

    10101 × 1011 = 10101*1+10101*2^1*1+10101*2^2*0+10101*2^3*1

    代码如下:

    long long multi(long long a,long long b,long long m) {
        long long ans=0;
    
        while(b) {
            if(b&1) (ans+=a) %= m;
            (a=a*2) %= m;
            b/=2;
        }
    
        return ans;
    }

    接下来本题的方法就是据矩阵乘法的快速幂

    (a 0

       c 1)自乘n次即可

    注意函数里也不要忘记了开longlong..一开始我函数里面的n写成了int,WA了一发。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 ll matrix[2][2],ans_matrix[2][2];
     8 ll m,n,a,c,g,x0;
     9 
    10 ll ksc(ll a,ll b)
    11 {
    12     ll ans=0; 
    13     while (b)
    14     {
    15         if (b&1) ans=(ans+a)%m;
    16         a=(a<<1)%m;
    17         b>>=1;
    18     }
    19     return ans;
    20 }
    21 
    22 void ksm(ll n)
    23 {
    24     ans_matrix[0][0]=ans_matrix[1][1]=1;
    25     ans_matrix[0][1]=ans_matrix[1][0]=0;
    26     while (n)
    27     {
    28         if (n&1)
    29         {
    30             ans_matrix[0][0]=ksc(ans_matrix[0][0],matrix[0][0]);
    31             ans_matrix[1][0]=(ksc(ans_matrix[1][0],matrix[0][0])+matrix[1][0])%m;
    32         }
    33         n>>=1;
    34         ll tmp1=ksc(matrix[0][0],matrix[0][0]);
    35         ll tmp2=(ksc(matrix[1][0],matrix[0][0])+matrix[1][0])%m;
    36         matrix[0][0]=tmp1,matrix[1][0]=tmp2;
    37     }
    38 }
    39 
    40 void init()
    41 {
    42     scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g); 
    43     matrix[0][0]=a%m,matrix[0][1]=0,matrix[1][0]=c%m,matrix[1][1]=1;
    44 }
    45 
    46 void get_ans()
    47 {
    48     ll ans=(ksc(ans_matrix[0][0],x0)+ans_matrix[1][0])%m;
    49     ans%=g;
    50     printf("%lld",ans);
    51 }
    52 
    53 int main()
    54 {
    55     //freopen("randoma.in","r",stdin);
    56     //freopen("randoma.out","w",stdout);
    57     init();
    58     ksm(n);
    59     get_ans();
    60     return 0;
    61 } 
  • 相关阅读:
    (兼容IE8)的渐变
    左侧固定,右侧自适应,两列等高并且自适应的第二种办法
    左侧定宽,右侧自适应,两列布局且等高
    下拉框重写
    在页面中输出当前客户端时间
    用哈希表去数组重复项,有详细注释
    求数组最大值、求和、乘法表、取整
    类似新浪微博输入字符计数的效果
    将博客搬至CSDN
    Mysql常用操作
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5657353.html
Copyright © 2011-2022 走看看