拓展欧几里得

http://poj.org/problem?id=2115

题意:for(int i = a ; i != b ; i += c) 问在mod2的k次方的条件下需要循环多少次使循环结束。

解法:转化为、a+cx ≡ b(mod 2的k次方)cx + 2的k次*y = b-a, 拓展欧几里得求解;

//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include ;
#include 
#include 
#include 
#include 
#include 
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define PI acos(-1)
using namespace std;
typedef long long ll ;
ll x , y , d;

void gcd(ll a , ll b , ll &d , ll &x , ll &y)
{
    if(b == 0)
    {
        x = 1 ;
        y = 0 ;
        d = a ;
    }
    else{
        gcd(b , a % b , d , x , y);
        ll t = x ;
        x = y ;
        y = t - (a / b) * y ;
    }
}

ll cal(ll a , ll b , ll c)
{
    gcd(a , b , d , x , y);
    if(c % d) return -1 ;
    else{
        x = (c / d) * x ;
        ll s = b / d ;
        return (x % s + s) % s ;//求得最小非负整数
    }
}

int main()
{
    ll a , b , c , k ;
    while(~scanf("%lld%lld%lld%lld" , &a , &b , &c , &k) && a+b+c+k)
    {
        ll B = pow(2 , k) , A = c , C = b - a ;
        ll an = cal(A , B , C) ;
        if(an == -1)
        {
            cout << "FOREVER" << endl ;
        }
        else{
            cout << an << endl ;
        }
    }

    return 0;
}

你可能感兴趣的:(拓展欧几里得)