hdu 3221 Brute-force Algorithm (矩阵快速幂+指数循环节)
题意:给出了一段伪代码。分析得知其实就是f[1]= a,f[2] = b,f[n]=f[n-1] * f[n-2]
思路:一眼题,和hdu4549很类似hdu4549解题报告
不同的是这道题中p不一定是质数(其实不是也无所谓啊…hdu4549只不过是因为1E9+7是指数,又用费马小定理化简了一下,这道理%phi(p)即可)
还有这道题让我知道了
首先我们知道指数循环节公式,也就是所谓的降幂公式为:**a^x = a^(x mod phi(c)+phi(c)) (mod c) x>=phi(c),(ps:后面的限制条件,在x**
括号里的话是错误的。只有当x<phi(c)的时候,这个公式才成立。
这道题就是反例,不加判断会wa。
1/* ***********************************************
2Author :111qqz
3Created Time :Sun 30 Oct 2016 11:46:33 PM CST
4File Name :code/hdu/3221.cpp
5************************************************ */
6
7#include <cstdio>
8#include <cstring>
9#include <iostream>
10#include <algorithm>
11#include <vector>
12#include <queue>
13#include <set>
14#include <map>
15#include <string>
16#include <cmath>
17#include <cstdlib>
18#include <ctime>
19#define fst first
20#define sec second
21#define lson l,m,rt<<1
22#define rson m+1,r,rt<<1|1
23#define ms(a,x) memset(a,x,sizeof(a))
24typedef long long LL;
25#define pi pair < int ,int >
26#define MP make_pair
27
28using namespace std;
29const double eps = 1E-8;
30const int dx4[4]={1,0,0,-1};
31const int dy4[4]={0,-1,1,0};
32const int inf = 0x3f3f3f3f;
33LL a,b,p,n;
34LL mod;
35LL euler( LL x)
36{
37 LL ret = 1;
38 for ( LL i = 2 ; i*i <= x; i++)
39 {
40 if (x%i==0)
41 {
42 x/=i;
43 ret*=(i-1);
44 while (x%i==0)
45 {
46 x/=i;
47 ret*=i;
48 }
49 }
50 }
51 if (x>1) ret*=(x-1);
52 return ret;
53}
54
55struct Mat
56{
57 LL mat[2][2];
58 void clear()
59 {
60 ms(mat,0);
61 }
62}M,M1;
63
64Mat operator * (Mat a,Mat b)
65{
66 Mat res;
67 res.clear();
68 for ( int i = 0 ; i < 2 ; i++)
69 for ( int j = 0 ; j < 2 ; j++)
70 for ( int k = 0 ; k < 2 ; k++)
71 {
72 res.mat[i][j] = (res.mat[i][j] + a.mat[i][k]*b.mat[k][j]);
73 if (res.mat[i][j]>=mod)
74 res.mat[i][j] = res.mat[i][j] % mod + mod;
75 }
76 return res;
77}
78Mat operator ^ (Mat a,LL b)
79{
80 Mat res;
81 res.clear();
82 for ( int i = 0 ; i < 2 ; i++) res.mat[i][i] = 1;
83 while (b>0)
84 {
85 if (b&1) res = res * a;
86 b = b >> 1LL;
87 a = a * a;
88 }
89 return res;
90}
91void init()
92{
93 M.clear();
94 M.mat[0][1] = M.mat[1][0] = M.mat[1][1] = 1;
95 M1.clear();
96 M1.mat[0][0] = 0 ;
97 M1.mat[1][0] = 1;
98}
99LL ksm( LL a,LL b,LL k)
100{
101 LL res = 1LL;
102 while (b>0)
103 {
104 if (b&1) res = (res * a) % k;
105 b = b >> 1LL;
106 a = ( a * a ) % k;
107 }
108 return res;
109}
110int main()
111{
112 #ifndef ONLINE_JUDGE
113 freopen("code/in.txt","r",stdin);
114 #endif
115 int T;
116 int cas = 0 ;
117 cin>>T;
118 while (T--)
119 {
120 scanf("%lld%lld%lld%lld",&a,&b,&p,&n);
121 printf("Case #%d: ",++cas);
122 if (n==1)
123 {
124 printf("%lld\n",a%p);
125 continue;
126 }
127 if (n==2)
128 {
129 printf("%lld\n",b%p);
130 continue;
131 }
132 init();
133 mod = euler(p);
134 Mat ans;
135 ans.clear();
136 ans = (M^(n-2))*M1;
137 LL x = ans.mat[0][0];
138 LL y = ans.mat[1][0];
139 LL ret = ksm(a,x,p)*ksm(b,y,p)%p;
140 printf("%lld\n",ret);
141 // printf("Case #%d: %lld\n",++cas,ret);
142 }
143
144 #ifndef ONLINE_JUDGE
145 fclose(stdin);
146 #endif
147 return 0;
148}