poj 2115 C Looooops(同余方程)
题解思路:
简单整理一下题意,就是让输出Cx≡(B-A)%(1<<k) 的最小非负整数解;
用ex_gcd求解即可;
n要强转为ll
ex_gcd:
ax+by=c;
ax+by=gcd(a,b)=gcd(b,a%b)=bx'+(a-a/b*b)y'
ax+by=bx'+(a-a/b*b)y'
ax+by=ay'+b(x'-a/b*y')
x=y' y=x'-a/b*y';
当取得gcd时a=gcd b=0;
所以 x=1,y=0为一组特解,回溯回去就是为a b对应的x,y;
求出的x,y为对应c为gcd(a,b)的情况,
对应为c应乘上差c/gcd(a,b);
如果c%gcd!=0方程无解;
求最小正整数解每次加最小对应区间 x为b%g y为a%g;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define int long long
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e5+50;
using namespace std;
int ex_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
else
{
int gcd=ex_gcd(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
}
}
#undef int
int main(){
#define int long long
int A,B,C,k;
while(cin>>A>>B>>C>>k)
{
if(!A&&!B&&!C&&!k) break;
int x,y;
int a=C;
int n=(ll)1<<k;
int b=B-A;
int gcd=ex_gcd(a,n,x,y);
if(b%gcd!=0) cout<<"FOREVER"<<endl;
else
{
x=(x*(b/gcd))%n;
int s=n/gcd;
x=(x%s+s)%s;
cout<<x<<endl;
}
}
return 0;
}