zoukankan      html  css  js  c++  java
  • BZOJ2875 [Noi2012]随机数生成器 【矩阵乘法 + 快速乘】

    题目

    栋栋最近迷上了随机算法,而随机数是生成随机算法的基础。栋栋准备使用线性同余法(Linear Congruential Me

    thod)来生成一个随机数列,这种方法需要设置四个非负整数参数m,a,c,X[0],按照下面的公式生成出一系列随机
    数X[n]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是多少就可以了。

    输入格式

    6个用空格分割的整数m,a,c,X[0],n和g,其中a,c,X[0]是非负整数,m,n,g是正整数。
    g<=10^8
    对于所有数据,n>=1,m>=1,a>=0,c>=0,X[0]>=0,g>=1。

    输出格式

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

    输入样例

    11 8 7 1 5 3

    输出样例

    2

    提示

    【样例说明】

    计算得X[n]=X[5]=8,故(X[n] mod g) = (8 mod 3) = 2

    题解

    按题意矩阵乘法
    这里写图片描述
    乘法会爆long long,要用快速乘
    快速乘有点像快速幂,化为二进制,乘法化加法防止溢出

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 1000000000;
    LL N,M,G,A,C,X;
    struct Matrix{
        LL s[2][2],n,m;
        Matrix(){s[0][0] = s[0][1] = s[1][1] = s[1][0] = n = m = 0;}
    }T,F0;
    LL mult(LL t,LL k){
        LL f = 0;
        for (; k; k >>= 1,t = (t + t) % M) if (k & 1) f = (f + t) % M;
        return f;
    }
    Matrix operator *(const Matrix& a,const Matrix& b){
        Matrix ans;
        if (a.m != b.n) return ans;
        ans.n = a.n; ans.m = b.m;
        for (int i = 0; i < ans.n; i++)
            for (int j = 0; j < ans.m; j++)
                for (int k = 0; k < a.m; k++)
                    ans.s[i][j] = (ans.s[i][j] + mult(a.s[i][k],b.s[k][j])) % M;
        return ans;
    }
    Matrix qpow(Matrix a,LL b){
        Matrix ans; ans.n = ans.m = a.n;
        for (int i = 0; i < ans.n; i++) ans.s[i][i] = 1;
        for (; b; b >>= 1,a = a * a)
            if (b & 1) ans = ans * a;
        return ans;
    }
    int main(){
        cin>>M>>A>>C>>X>>N>>G;
        T.n = T.m = 2;
        T.s[0][0] = A; T.s[0][1] = 1; T.s[1][0] = 0; T.s[1][1] = 1;
        F0.n = 2; F0.m = 1; F0.s[0][0] = X; F0.s[1][0] = C;
        Matrix F = qpow(T,N) * F0;
        LL ans = (F.s[0][0] % M + M) % M;
        cout<<ans % G<<endl;
        return 0;
    }
    
  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282700.html
Copyright © 2011-2022 走看看