题目:http://poj.org/problem?id=2115;
题意:给出A,B,C经过多少次循环能结束,不能则输出FOREVER,且本题所有数值在2^k内;
分析:不难看出本题意图为求解A+c*x=b(mod 2^k)(由于三个横线不好打就用等号代替),显然是求解一次同余方程的最小值,采用扩展欧几里得算法解答;
代码:
#include <set> #include <map> #include <stack> #include <queue> #include <math.h> #include <vector> #include <string> #include <utility> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <functional> using namespace std; long long gcd(long long a,long long b){ if(b==0)return a; return gcd(b,a%b); } void _gcd(long long a,long long b,long long &x,long long &y){ if(b==1){ x=1; y=1-a; } else{ long long x1,y1; _gcd(b,a%b,x1,y1); x=y1; y=x1-(a/b)*x; } }//拓展欧几里得 int main(){ long long a,b,c,k; while(cin>>a>>b>>c>>k){ if(a==0&&b==0&&c==0&&k==0)break; long long num=1ll<<k; long long sum=b-a; long long g=gcd(c,num); if(sum%g!=0){ puts("FOREVER"); continue; } long long x,y; long long a_1,b_1; a_1=c/g; b_1=num/g; _gcd(a_1,b_1,x,y); sum/=g; x=(x*sum%b_1+b_1)%b_1; cout<<x<<endl; } return 0; }