poj_2115-C Looooops

这里写图片描述

大概意思是:给你一个数A,若A不等于B则加C,如果超过B则mod 2^k,问你要多少次才能等于B。若不能等于B则输出“FOREVER”.

题解;

设x是循环次数,y是2^k被整除(A+xC)的值
由题意得:
(A+xC)mod 2^k=B
(A+xC)-y*2^k=B
Cx=(B-A)(mod 2^k)
得出线性同余方程,然后用扩展欧几里德算法求出最小值x即为答案。
不知道的点:扩展欧几里德算法

代码:

 1  1 #include <stdio.h>      
 2  2 #include <iostream>      
 3  3 #include <algorithm>      
 4  4 #include <sstream>      
 5  5 #include <stdlib.h>      
 6  6 #include <string.h>      
 7  7 #include <limits.h>      
 8  8 #include <string>      
 9  9 #include <time.h>      
10 10 #include <math.h>      
11 11 #include <queue>      
12 12 #include <stack>      
13 13 #include <map>   
14 14 using namespace std;
15 15 typedef long long ll;
16 16 
17 17 void gcd(ll a,ll b,ll& d,ll& x,ll& y){
18 18     if(!b){
19 19         d=a; x=1; y=0;
20 20     }else{
21 21         gcd(b,a%b,d,y,x);
22 22         y=y-x*(a/b);
23 23     }
24 24 }
25 25 
26 26 int main(){
27 27     ll a,b,c,k;
28 28     while (~scanf("%lld%lld%lld%lld",&a,&b,&c,&k)&&(a||b||c||k)){
29 29         ll m=1ll<<k;
30 30         ll d,x,y;
31 31         gcd(c,m,d,x,y);
32 32         ll e=b-a;
33 33         if(e%d!=0){
34 34             printf("FOREVER
");
35 35         }else{
36 36             x=(x*(e/d))%m; 
37 37             x=(x%(m/d)+m/d)%(m/d);
38 38             printf("%lld
",x);
39 39         }
40 40     }
41 41     return 0;
42 42 }
原文地址:https://www.cnblogs.com/zyx-crying/p/9319503.html