2012 NOI 第一试 随机数生成器

 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;
} 
posted @ 2017-11-10 22:55  Exception2017  阅读(112)  评论(0编辑  收藏  举报