lg2044

链接:lg2044

Description

  • 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础。栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随
  • 机数列,这种方法需要设置四个非负整数参数m,a,c,X[0],按照下面的公式生成出一系列随机数{Xn}:
  • X[n+1]=(aX[n]+c) mod m
  • 其中mod m表示前面的数除以m的余数。从这个式子可以看出,这个序列的下一个数总是由上一个数生成的。
  • 用这种方法生成的序列具有随机序列的性质,因此这种方法被广泛地使用,包括常用的C++和Pascal的产生随机数的库函数使用的也是这
  • 种方法。
  • 栋栋知道这样产生的序列具有良好的随机性,不过心急的他仍然想尽快知道X[n]是多少。由于栋栋需要的随机数是0,1,…,g-1之间的,
  • 他需要将X[n]除以g取余得到他想要的数,即X[n] mod g,你只需要告诉栋栋他想要的数X[n] mod g是多少就可以了。

    Input

  • 输入包含6个用空格分割的整数m,a,c,X[0],n和g,其中a,c,X[0]是非负整数,m,n,g是正整数。

    Output

  • 输出一个数,即X[n] mod g

    Sample Input

    11 8 7 1 5 3

    Sample Output

    2

    题解

  • 矩阵快速幂模板
  • 注意要用快速乘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
using namespace std;
ll n,m,A,c,d,p;
struct mat{
ll a[2][2];
};
mat T={1,1,0,1};
void readin(){
ios::sync_with_stdio(false);
cin>>m>>A>>c>>d>>n>>p;
}

ll K(ll x,ll y){
ll ans=0;
x%=m;y%=m;
while(y){
if(y&1)ans=(ans+x)%m;
x=(x+x)%m;
y>>=1;
}
return ans;
}

mat mul(mat x,mat y){
mat ans={0};
rep(i,0,1)rep(j,0,1)rep(k,0,1){
//cout<<"i="<<i<<"j="<<j<<' '<<x.a[i][k]*y.a[k][j]<<' '<<ans.a[i][j]<<endl;
//cout<<K(x.a[i][k],y.a[k][j])<<endl;
ans.a[i][j]=(ans.a[i][j]+K(x.a[i][k],y.a[k][j]))%m;
}
return ans;
}

void solve(){
readin();
T.a[0][0]=A;
mat ans={0,d,0,c};
while(n){
if(n&1)ans=mul(T,ans),n--;
T=mul(T,T);
n>>=1;
}
cout<<ans.a[0][1]%p<<endl;
}

int main(){
solve();
return 0;
}