E - 隨機數生成器
阿新 • • 發佈:2020-07-21
直接模擬矩陣乘法即可
但是,注意資料範圍,我們long long乘法會炸精度,因此採用快速乘。
快速乘,類似快速冪的思想,大概就是把乘號改加號
int mul(int x,int y){
int z = 0;
while(y){
if(y & 1) z = z + x;
y >>= 1;
x = x + x;
}
return z;
}
#include<bits/stdc++.h> using namespace std; long long mod,A,C,x0,xn,n,G; struct jz{ long long g[4][4]; void init(){ memset(g,0,sizeof(g)); } void one(){ memset(g,0,sizeof(g)); for(int i = 1; i <= 2; ++ i) g[i][i] = 1; } }; long long mul(long long x,long long y){ long long z = 0; while(y){ if(y & 1) z = (z + x) % mod; y >>= 1; x = (x + x) % mod; } return z; } jz operator * (jz a, jz b){ jz c; c.init(); for(int i = 1; i <= 2; ++ i) for(int j = 1; j <= 2; ++ j) for(int k = 1; k <= 2; ++ k) c.g[i][j] = ( c.g[i][j] + mul(a.g[i][k], b.g[k][j])) % mod; return c; } jz ksm(jz x,long long y){ jz z; z.one(); while(y){ if(y & 1) z = z * x; y >>= 1; x = x * x; } return z; } jz a; int main(){ scanf("%lld%lld%lld%lld%lld%lld",&mod,&A,&C,&x0,&n,&G); a.g[1][1] = A; a.g[1][2] = 1; a.g[2][1] = 0; a.g[2][2] = 1; a = ksm(a, n); long long xn = (mul(a.g[1][1],x0) + mul(a.g[1][2],C))% mod; printf("%lld\n",(xn % G + G) % G); return 0; }