Rivest是密码学专家。近日他正在研究一种数列E = {E[1],E[2],……,E[n]},
且E[1] = E[2] = p(p为一个质数),E[i] = E[i-2]*E[i-1] (若2<i<=n)。
例如{2,2,4,8,32,256,8192,……}就是p = 2的数列。在此基础上他又设计了一种加密算法,该算法可以通过一个密钥q (q < p)将一个正整数n加密成另外一个正整数d,计算公式为:d = E[n] mod q。现在Rivest想对一组数据进行加密,但他对程序设计不太感兴趣,请你帮助他设计一个数据加密程序。
第一行读入m,p。其中m表示数据个数,p用来生成数列E。 以下有m行,每行有2个整数n,q。n为待加密数据,q为密钥。 数据范围: 0 < p n< 2^31 0 < q < p 0 < m <= 5000。
将加密后的数据按顺序输出到文件 第i行输出第i个加密后的数据。 输入样例1 2 7 4 5 4 6 输入样例2 4 7 2 4 7 1 6 5 9 3
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<algorithm>
5 using namespace std;
6 #define int long long
7 __attribute__((optimize("O3")))int read() {
8 int s=0,f=1;
9 char ch=getchar();
10 while(ch>‘9‘||ch<‘0‘) {
11 if(ch==‘-‘) {
12 f=-1;
13 }
14 ch=getchar();
15 }
16 while(ch>=‘0‘&&ch<=‘9‘) {
17 s=(s<<1)+(s<<3)+(ch^48);
18 ch=getchar();
19 }
20 return s*f;
21 }
22 __attribute__((optimize("O3")))int get_phi(int t) {
23 int kk=t;
24 for(int i=2; i*i<=t; i++) {
25 if(t%i==0) {
26 kk-=kk/i;
27 while(t%i==0) {
28 t/=i;
29 }
30 }
31 }
32 if(t>1) {
33 kk-=kk/t;
34 }
35 return kk;
36 }
37 __attribute__((optimize("O3")))void fast(long long a[][3],long long b[][3],int q) {
38 long long temp[3][3]= {0};
39 for(int i=1; i<=2; i++) {
40 for(int j=1; j<=2; j++) {
41 for(int k=1; k<=2; k++) {
42 temp[i][j]=(temp[i][j]+a[i][k]*b[k][j])%q;
43 }
44 }
45 }
46 b[1][1]=temp[1][1]%q;
47 b[1][2]=temp[1][2]%q;
48 b[2][1]=temp[2][1]%q;
49 b[2][2]=temp[2][2]%q;
50 }
51 __attribute__((optimize("O3")))long long speed(int i,int q) {
52 long long sin[3][3],a[3][3];
53 sin[1][1]=1;
54 sin[2][1]=1;
55 sin[1][2]=1;
56 sin[2][2]=0;
57 a[1][1]=1;
58 a[1][2]=0;
59 a[2][1]=0;
60 a[2][2]=1;
61 for(; i; i>>=1,fast(sin,sin,q)) {
62 if(i&1) {
63 fast(sin,a,q);
64 }
65 }
66 return a[1][2];
67 }
68 int m,p,q,n;
69 __attribute__((optimize("O3")))long long mul(int a,long long t,int mod) {
70 long long ans=1;
71 for(; t; t>>=1,(a=a*a%mod)) {
72 if(t&1) {
73 (ans=a*ans%mod);
74 }
75 }
76 return ans;
77 }
78 __attribute__((optimize("O3")))signed main() {
79 m=read();
80 p=read();
81 for(int i=1; i<=m; i++) {
82 n=read();
83 q=read();
84 int ji=get_phi(q);
85 int x=speed(n,ji);
86 x=x%ji;
87 long long ans=mul(p,x,q)%q;
88 printf("%lld\n",ans);
89 }
90 return 0;
91 }