1. 程式人生 > >bzoj2875隨機數生成器

bzoj2875隨機數生成器

name long pro ret div 隨機數生成 https ID nbsp

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=2875

矩陣乘裸題。

如果直接乘的話會爆long long,所以用加法代替乘,過程中不斷取模。

加法應是快速乘,不要O(n)循環……

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
ll n,m,g,a,c,ans,x;
ll mul(ll u,ll v)
{
    ll ret=0,tp=u;
    while(v)
    {
        
if(v&1)(ret+=tp)%=m; (tp+=tp)%=m;v>>=1; } return ret; } struct Matrix{ ll v[2][2]; Matrix operator *(const Matrix &b)const { Matrix tp;memset(tp.v,0,sizeof tp.v); for(int i=0;i<=1;i++) for(int j=0;j<=1;j++) for(int
k=0;k<=1;k++) (tp.v[i][j]+=mul(v[i][k],b.v[k][j]))%=m; return tp; } }res,ct; void init() { scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x,&n,&g); n--; res.v[0][0]=a;res.v[0][1]=1; res.v[1][0]=0;res.v[1][1]=1; memcpy(ct.v,res.v,sizeof
res.v); } int main() { init(); while(n) { if(n&1)res=res*ct; ct=ct*ct;n>>=1; } ans=(mul(res.v[0][0],x)+mul(res.v[0][1],c))%m%g; printf("%lld",ans); return 0; }

bzoj2875隨機數生成器