题目链接:http://poj.org/problem?id=2115
题意:初始值为A,每次加上C,问加多少次可以加到B,因为是用一个k位的二进制计算器,所以每次加完都要mod 2^k
思路:扩展欧几里得。A+Cx - 2^k * t = B => Cx + 2^k*(-t) = B-A
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod %100000007
#define mp make_pair
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m=(l+r)>>1
int exgcd(LL a,LL b,LL &x,LL &y) //返回最大公约数,x,y存的是一组解
{
if(b==0)
{
x=1;
y=0;
return a;
}
LL r=exgcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return r;
}
bool modular_linear_equation(LL A,LL C,LL B) // Ax+By = C
{
LL x,y,x0;
LL d=exgcd(A,B,x,y);
if(C%d)
return false;
x0=x*(C/d); //特解
LL xx = B/d; //通解的累加量
LL ans = (x0%xx+xx)%xx; //求出最小的非负整数解。
printf("%I64d\n",ans);
return true;
}
LL A,B,C;
int k;
int main()
{
while( ~scanf("%I64d %I64d %I64d %d",&A,&B,&C,&k) )
{
if ( A + B + C + k == 0 ) break;
LL m = (LL)1<<k;
if ( !modular_linear_equation( C , B - A , m ) ) puts("FOREVER");
}
return 0;
}