1. 程式人生 > >【LOJ】#2670. 「NOI2012」隨機數生成器

【LOJ】#2670. 「NOI2012」隨機數生成器

sin 快速 con || include define out source efi

題解

矩陣乘法,註意需要快速乘
矩陣2*2
a c
0 1

代碼

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define enter putchar(‘\n‘)
#define space putchar(‘ ‘)
#define MAXN 70005
//#define ivorysi
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
    res = 0
;char c = getchar();T f = 1; while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) { res = res * 10 + c - ‘0‘; c = getchar(); } res = res * f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar(‘-‘
);} if(x >= 10) out(x / 10); putchar(‘0‘ + x % 10); } int64 M,a,c,X0,N,G; int64 inc(int64 a,int64 b) { return a + b >= M ? a + b - M : a + b; } int64 mul(int64 a,int64 b) { int64 res = 0,t = a; while(b) { if(b & 1) res = inc(res,t); t = inc(t,t); b >>= 1; } return
res; } struct Matrix { int64 f[2][2]; Matrix() {memset(f,0,sizeof(f));} friend Matrix operator * (const Matrix &a,const Matrix &b) { Matrix c; for(int i = 0 ; i <= 1 ; ++i) { for(int j = 0 ; j <= 1 ; ++j) { for(int k = 0 ; k <= 1 ; ++k) { c.f[i][j] = inc(c.f[i][j],mul(a.f[i][k],b.f[k][j])); } } } return c; } }A,ans; void fpow(int64 c) { Matrix t = A; while(c) { if(c & 1) ans = ans * t; t = t * t; c >>= 1; } } void Solve() { read(M);read(a);read(c);read(X0);read(N);read(G); ans.f[0][0] = ans.f[1][1] = 1; A.f[0][0] = inc(a % M,M);A.f[0][1] = inc(c % M,M); A.f[1][1] = 1; fpow(N); int64 res = inc(mul(ans.f[0][0],X0),ans.f[0][1]); res = res % G; out(res);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }

【LOJ】#2670. 「NOI2012」隨機數生成器