题目地址:http://poj.org/problem?id=2115
题意:for (variable = A; variable != B; variable += C)
variable= variable%2k.
问循环是否能够终止,以及循环的次数。
思路:扩展欧几里得的基础题。
假设循环x次,则a+cx=b(mod 2^k)
cx=(b-a)(mod 2^k)
cx+2ky=(b-a) (y任意整数)
判断(b-a)是否整除gcd(c,2k),否的话方程无解,循环不能够终止:是的话,进行扩展欧几里得求解即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
void Ex_gcd(long long a,long long b, long long &x,long long &y)
{
if(b == 0)//µÝ¹é³ö¿Ú
{
x = 1;
y = 0;
return;
}
long long x1, y1;
Ex_gcd(b, a%b, x1, y1);
x = y1;
y = x1-(a/b)*y1;
}
long long quick(int k)
{
long long b=1;
long long m=2;
while(k)
{
if(k&1)
b=b*m;
m=m*m;
k=k>>1;
}
return b;
}
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
int main()
{
long long k,a,b,c;
while(scanf("%lld%lld%lld%lld",&a,&b,&c,&k)!=EOF)
{
if(k==0&&a==0&&b==0&&c==0)
break;
long long m=quick(k);
long long g=gcd(c,m);
long long n=b-a;
if(n%g)
{
printf("FOREVER\n");
continue;
}
long long x,y;
Ex_gcd(c,m,x,y);
m=m/g;
x=x*(n/g);
x=(x%m+m)%m;
printf("%lld\n",x);
}
return 0;
}