码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-05-22 10:56:27      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

 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(同余定理找循环节 / 快速幂)

标签:

原文地址:http://www.cnblogs.com/zstu-jack/p/5516264.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!