hdu 5690(同余定理找循环节 / 快速幂)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5690(同余定理找循环节 / 快速幂)相关的知识,希望对你有一定的参考价值。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define lld I64d
 5 #ifdef _WIN32
 6 #define LLD "%I64d"
 7 #else
 8 #define LLD "%lld"
 9 #endif
10 const int N = 10000 + 100;
11 ll x,m,c,k;
12 int pos[N];
13 /**
14  * 同余定理: 
15  * (a+b) mod n = ((a mod n) + (b mod n)) mod n;
16  * ab mod n = (a mod n)*(b mod n) mod n;
17  *
18  *555 mod n = (550 + 5) mod n = 550 mod n + 5 mod n
19  *                              = ((55 mod n) * (10 mod n)     + 5 mod n) mod n;
20  *  g(i) mod n = (g(i-1) * 10 + 5) mod n;
21  *
22  * 记录上一个相同值出现的位置,求出循环节,然后使 i 逼近 m,
23  * tmp 继续 * 10 + x 直到 m;
24  * */
25 int main(){
26     int T,kase = 1;
27     scanf("%d",&T);
28     while(T--){
29         scanf("%lld%lld%lld%lld",&x,&m,&k,&c);
30         memset(pos,-1,sizeof(pos));
31         ll tmp = 0;
32         ll d = 0 , now = 0;
33         for(int i = 1 ; i <= N; i ++){
34             tmp = (tmp * 10 + x) % k; // 同余定理
35             if(pos[tmp] == -1){
36                 pos[tmp] = i;
37             }else{
38                 d = i - pos[tmp];
39                 now = i;
40                 break;
41             }
42         }
43         ll ansn = now + (m - now) / d * d;
44         if(ansn > m) ansn -= d;
45         while(++ansn <= m){
46             tmp = (tmp * 10 + x) % k;
47         }
48         if(tmp == c){
49             printf("Case #%d:\nYes\n",kase++);
50         }else{
51             printf("Case #%d:\nNo\n",kase++);
52         }
53     }
54 }

 

 

 

快速幂:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define lld I64d
 5 ll x,m,c,k;
 6 ll quickmod(ll a,ll b,ll mod){
 7     ll ret = 1;
 8     while(b){
 9         if(b & 1) ret = ret*a % mod;
10         a = a*a % mod;
11         b >>= 1;
12     }
13     return ret;
14 }
15 int main(){
16     int T,kase = 1;
17     scanf("%d",&T);
18     while(T--){
19         scanf("%lld%lld%lld%lld",&x,&m,&k,&c);
20         ll mod = 9*k;
21         ll ret = quickmod(10,m,mod);
22         if((ret%mod-1%mod)*(x%mod)%mod == 9*c){
23 //        if(ret*x%mod - x%mod == 9*c){
24             printf("Case #%d:\nYes\n",kase++);
25         }else{
26             printf("Case #%d:\nNo\n",kase++);
27         }
28     }
29     return 0;
30 }
31 /**
32  * 
33  * (10^m-1)/9*x%k == c
34  * (10^m-1)*x/9%k == c
35  *  ***由于 (10^m-1)*x % 9 == 0; 
36  * *** ----> (10^m-1)*x % (9*k) == 9*c;
37  *          ((10^m % 9*k) - 1 % 9*k) * x % (9*k)    mod(9*k)
38  * */

 

以上是关于hdu 5690(同余定理找循环节 / 快速幂)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5690——All X——————快速幂 | 循环节

hdu1576-A/B-(同余定理+乘法逆元+费马小定理+快速幂)

HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)

HDU 5690 All X 暴力循环节

HDU 5690 矩阵快速幂

HDU 5690 All X (快速幂)