http://poj.org/problem?id=2115
题意:对于C的循环(for i = A; i != B; i+=C)问在k位存储系统内循环多少次结束;
若循环有限次能结束输出次数,否则输出 FOREVER;
解:设x为循环次数;
(A+C*x)%2^k = B;
则 C*x+A = 2^k*y+B;
所以 C*x - 2^k*y = B-A; 类似于a*x+b*y = c (或 a*x = c(mod b))模线性方程的形式,根据扩展欧几里得算法解决,模板题。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#define LL long long
#define _LL __int64
#define eps 1e-8
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10;
/*
(A+C*x)%2^k = B;
那么 A + C*x = 2^k * y + B;
C*x - 2^k*y = B-A;
*/
LL extend_gcd(LL a, LL b, LL &x, LL &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
LL d = extend_gcd(b,a%b,x,y);
LL t = x;
x = y;
y = t - a/b*y;
return d;
}
int main()
{
int A,B,C,k;
LL a,b,c;
LL x,y;
while(~scanf("%d %d %d %d",&A,&B,&C,&k))
{
if(A == 0 && B == 0 && C == 0 && k == 0)
break;
a = C;
b = 1LL<<k;
c = B-A;
LL d = extend_gcd(a,b,x,y);
if(c%d != 0)
{
printf("FOREVER\n");
continue;
}
x = x * (c/d);
x = (x%(b/d) + (b/d)) % (b/d);
printf("%lld\n",x);
}
return 0;
}