zoukankan      html  css  js  c++  java
  • [vijos1725&bzoj2875]随机数生成器<矩阵乘法&快速幂&快速乘>

    题目链接:https://vijos.org/p/1725

        http://www.lydsy.com/JudgeOnline/problem.php?id=2875

    这题是前几年的noi的题,时间比较久远了所以就不是那么的难了

    这是一个非常裸的矩阵乘法,一般矩阵乘法就是矩阵+快速幂

    只是这道题在矩阵乘法的时候单纯的乘法会溢出,所以还要用到快速乘法

    网上也有说用long double黑科技的,虽然我不是很懂那个东东

     

    构造矩阵

    单位矩阵a,c

                  0,1

    答案矩阵   Xi-1

                     1

    我的这个矩阵构造可能和一般的不同,主要是我受斐波拉契的毒害太深了QAQ

    这题我一开始只是用的int,只过了一半,longlong后过了17组,最后三组加上快速乘优化才成功通过

    然后如果是在vijos提交要注意一点就是在vijos上输出longlong型要用I64d来输出

     

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<iostream>
     7 #include<queue>
     8 #define ll long long
     9 using namespace std;
    10 
    11 ll n,m,a,c,g,x0;
    12 ll ans[4][4],b[4][4];
    13 
    14 void read(ll & xx){
    15     xx=0;ll ff=1;char ch=getchar();
    16     while(ch<'0'||ch>'9'){if(ch=='-')ff=-1;ch=getchar();}
    17     while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
    18     xx*=ff;
    19 }
    20 
    21 ll sum(ll x,ll y){
    22     ll cnt=0;
    23     while(y){
    24         if(y&1){
    25             cnt=(cnt+x)%m;
    26         }y>>=1;x=(x+x)%m;
    27     }return cnt;
    28 }
    29 
    30 void add(){
    31         ll z[4][4];memset(z,0,sizeof(z));
    32         for(int i=1;i<=2;i++){
    33             for(int j=1;j<=2;j++){
    34                 for(int k=1;k<=2;k++){
    35                     z[i][j]=(z[i][j]%m+sum(b[k][j],b[i][k])%m)%m;
    36                 }
    37             }
    38         }        
    39         for(int i=1;i<=2;i++)
    40         for(int j=1;j<=2;j++)
    41             b[i][j]=z[i][j]%m;    
    42 }
    43 
    44 void mul(ll y){
    45     while(y){
    46         if(y&1){
    47             ll z[4][4];z[1][1]=z[2][1]=0;
    48             for(int i=1;i<=2;i++){
    49                 for(int j=1;j<=1;j++){
    50                     for(int k=1;k<=2;k++){
    51                         z[i][j]=(z[i][j]%m+sum(ans[k][j],b[i][k])%m)%m;
    52                     }
    53                 }
    54             }
    55             ans[1][1]=z[1][1]%m; 
    56         }
    57         y>>=1;
    58         add();
    59     }
    60 }
    61 
    62 int main(){
    63     read(m),read(a),read(c),read(x0),read(n),read(g);
    64     ans[1][1]=x0%m;ans[2][1]=1;
    65     b[1][1]=a%m;b[1][2]=c%m;b[2][2]=1;
    66     mul(n);
    67     //printf("%lld",ans[1][1]%g);
    68     cout<<ans[1][1]%g;
    69 }
    View Code

    【总结】

    活用快速幂的模板,毕竟这东西真的很神奇

     

  • 相关阅读:
    带箭头提示框
    文本溢出显示省略号
    Git高级操作
    sublime text 2 破解
    python如何画三维图像?
    pytorch梯度下降法讲解(非常详细)
    pytorch数学运算与统计属性入门(非常易懂)
    pytorch张量数据索引切片与维度变换操作大全(非常全)
    pytorch中tensor张量数据基础入门
    pytorch深度学习神经网络实现手写字体识别
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7802485.html
Copyright © 2011-2022 走看看