1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
/*2012 NOI第一试 第一题 随机数生成器 */ #include<cstdio> long long m,a,c,x0,n; long long t11,t12,t21,t22; long long s11,s12,s21,s22; long long x11,x12,x21,x22; long long ans; int b[70]; int d[70]; int num2; int g; long long f(long long a,long long b){ long long s; while(a>0){ d[++num2]=a%2; a/=2; } long long t=b; if(d[1]==1)s=t;else s=0; for(int i=2;i<=num2;i++){ t=(t+t)%m; if(d[i]==1) s=(s+t)%m; } return s; } int main(){ freopen("random.in","r",stdin); freopen("random.out","w",stdout); scanf("%lld%lld%lld%lld%lld%d",&m,&a,&c,&x0,&n,&g); //先把n转换成2进制 int i=0; int num1=0; while(n>0){ b[++i]=n%2; n/=2; num1++;//数组长度 } // for(int j=1;j<=num1;j++){ // printf("%d",b[j]); // } //2.初始化t矩阵和S矩阵 t11=a;t12=0; t21=c;t22=1; //矩阵倍增 if(b[1]==1){ s11=t11;s12=t12; s21=t21;s22=t22; }else{ s11=1;s12=0; s21=0;s22=1; } //循环倍增 for(int i=2;i<=num1;i++){ //t矩阵×t矩阵存回t x11=(f(t11,t11)+f(t12,t21))%m;x12=(f(t11,t12)+f(t12,t22))%m; x21=(f(t21,t11)+f(t21,t22))%m;x22=(f(t21,t12)+f(t22,t22))%m; t11=x11;t12=x12; t21=x21;t22=x22; if(b[i]==1){ //s成t存s x11=(f(s11,t11)+f(s12,t21))%m;x12=(f(s11,t12)+f(s12,t22))%m; x21=(f(s21,t11)+f(s22,t21))%m;x22=(f(s21,t12)+f(s22,t22))%m; s11=x11;s12=x12; s21=x21;s22=x22; } } ans=(x0*s11+x21)%m%g; //输出 printf("%d",ans); return 0; } |
转载于:https://www.cnblogs.com/Exception2017/p/10252113.html