代码改变世界

小L的随机数(矩阵快速幂)

2019-08-13 20:33  木木王韦  阅读(150)  评论(0)    收藏  举报

小L的随机数

时间限制: 1 Sec 内存限制: 128 MB
提交: 425 解决: 136
[提交] [状态] [讨论版] [命题人:外部导入]
题目描述
 随机数是生成随机算法的基础,小L准备使用线性同余法(Linear Congruential Method)来生成一个随机数列,这种方法需要设置四个非负整数参数m, a, c, x0按照下面的公式生成出一系列随机数 : Xn+1 = (a * Xn + c) mod m ,小L现在想知道这个数列第n个数是多少,由于他只需要生成小于g的随机数,所以你只需要告诉他Xn mod g的结果即可。
输入
输入一行6个整数,分别表示m, a, c, X0, n, g 。(n ≤ 106,1 ≤ m, a, c, X0 , g ≤231 − 1)
输出
一行一个整数表示Xn
样例输入 Copy
233 3 3 3 3 333
样例输出 Copy
120

暴力没写出来,换了矩阵快速幂,一直忽略了n为1的情况

ac代码:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
 
struct node{
    long long int m[10][10];
};
int f=3;
long long int mod;
node a,b,c;
int m,aa,cc,g,n,x;
 
node mul(node a,node b){
    node ans;
    memset(ans.m,0,sizeof(ans.m));
    for(int i=1;i<=f;i++){
        for(int j=1;j<=f;j++){
            for(int k=1;k<=f;k++)
            ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
        }
    }
    return ans;
}
 
node ksm(node a,int b){
    node res;
    memset(res.m,0,sizeof(res.m));
    for(int i=1;i<=f;i++) res.m[i][i]=1;
    while(b){
        if(b&1){
            res=mul(res,a);
        }
        b>>=1;
        a=mul(a,a);
    }
    return res;
    }
int main(){
    memset(a.m,0,sizeof(a.m));
    memset(b.m,0,sizeof(b.m));
    memset(c.m,0,sizeof(c.m));
    cin>>m>>aa>>cc>>x>>n>>g;
    a.m[1][1]=x;
    mod=m;
    a.m[2][1]=1;
    a.m[3][1]=1;
    b.m[1][1]=aa;
    b.m[1][3]=cc;
    b.m[2][1]=1;
    b.m[3][3]=1;
    c=ksm(b,n);
     
//  for(int i=1;i<=f;i++){
//      for(int j=1;j<=3;j++){
//          cout<<a.m[i][j]<<" ";
//      }
//      cout<<endl;
//  }
//  for(int i=1;i<=f;i++){
//      for(int j=1;j<=3;j++){
//          cout<<b.m[i][j]<<" ";
//      }
//      cout<<endl;
//  }
//  for(int i=1;i<=f;i++){
//      for(int j=1;j<=3;j++){
//          cout<<c.m[i][j]<<" ";
//      }
//      cout<<endl;
//  }
    c=mul(c,a);
//  for(int i=1;i<=f;i++){
//      for(int j=1;j<=3;j++){
//          cout<<c.m[i][j]<<" ";
//      }
//      cout<<endl;
//  }
    cout<<c.m[1][1]%g<<endl;
}