poj 2115C Looooops

题目: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;
}


你可能感兴趣的:(数学,poj,同余)