# [vijos1725&bzoj2875]随机数生成器<矩阵乘法&快速幂&快速乘>

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

0,1

1

 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
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;
59     }
60 }
61
62 int main(){
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

【总结】

posted @ 2017-11-10 09:32  Danzel♂  阅读(85)  评论(0编辑  收藏