http://poj.org/problem?id=2115
题意:给出a,b,c<=1e9,k<=32 求出p 使得 (a+pc)mod2^k=b
a+pc同余b(mod2^k) 2^kx=a+pc-b -> 2^kx-pc=a-b 利用exgcd求出x,p即可
最小正整数解
x=x0+(k/d)*n 通解 任意解:x同余x0 mod(k/d)
x0%(k/d)显然和x0同余(k/d)
x=(x0%k/d+k/d)%mod 为最小正整数解
x0%k/d为正 x显然为最小正整数解
x0%k/d为负,x0%k/d+k/d显然与x0同余k/d 也为正数 所以为最小正整数解
#include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <cstdio> using namespace std; typedef long long ll; const int N=2e5+20; ll a,b,c,k; ll x,y; ll exgcd(ll a,ll b) { ll d; if(b==0) { y=0,x=1; return a; } d=exgcd(b,a%b); ll t=y; y=x-a/b*y; x=t; return d; } int main() { while(cin>>a>>b>>c>>k&&(a+b+c+k)) { k=(ll)1ll<<k; ll d=exgcd(c,k); if((b-a)%d||(a!=b&&c==0)) puts("FOREVER"); else { // x=x*(b-a)/d; //x=x0+(k/d)*n 通解 任意解 x同余x0 mod(k/d) //x0%(k/d)显然和x0同余(k/d) //现在要使x为最小正整数解 如果x0%k/d可能为正或者负 所以x=(x0%k/d+k/d)%mod 为最小正整数解 ll t=k/d; x=(x%t+t)%t; //最小正整数解 cout<<x<<endl; } } return 0; }
时间: 2024-10-24 11:39:06