POJ 2115 C Looooops
解题思路:
求解(P*x)%M=Q,最小的非负整数x;即求解P*x + M*y = Q,令p=d1*gcd(P, M),M=d2*gcd(P, M)
所以方程变为 d1 * x + d2 * y = Q / gcd(P,M),若gcd|Q,令d3 = Q/gcd(P,M),否则,解不存在。
d1 * x + d2 * y = d3 ,且gcd(d1, d2)=1
利用扩展的欧几里得原理求解d1 * x' + d2 * y' = 1
方程的通解变为 x = x‘ * d3 + d2 * i, y = y’ * d3 - d1 * i。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
using namespace std;
typedef __int64 ll;
ll Extend_GCD(ll a, ll b, ll& x, ll& y)
{
if(b==0){x=1,y=0;return a;}
else
{
ll tx, ty;
ll v = Extend_GCD(b, a%b, tx, ty);
x=ty, y=tx-a/b*ty;
return v;
}
}
int main()
{
int i,j,k;
ll A, B, C, D, x, y, g;
while(scanf("%I64d %I64d %I64d %d", &A, &B, &C, &k)&&A+B+C+k)
{
D=(ll)1<<k, B = (B-A+D)%D;
g = Extend_GCD(C, D, x, y);
if(B%g)printf("FOREVER\n");
else
{
B/=g,C/=g,D/=g;
x*=B, x%=D;
if(x<0)x=(x+D)%D;
printf("%I64d\n",x);
}
}
return 0;
}