POJ C Looooops
阿新 • • 發佈:2019-02-09
a*x和b同餘N時,當b為gcd(a,N)的倍數時有整數解,設x0 = ex_gcd(a,N,b),可得符合條件的x的集合為:x0+k*n'(n' = N / gcd(a,N));
題目很簡單,其實就是用尤拉定理求一下逆元即可,注意求出的逆元可能不是最小正整數。需要用公式求一下最小正整數即可。
#include<cstdio> #include<cstring> #include<algorithm> #define ll __int64 using namespace std; ll N; void ex_gcd(ll a, ll b, ll&d, ll& x, ll& y){ if (b == 0){ d = a; x = 1; y = 0; return; } ex_gcd(b,a%b,d,y,x); y -= (a/b)*x; } ll gcd; bool mark; ll modular(ll a, ll b){ ll x, y, d; ex_gcd(a,N,d,x,y); gcd = d; if (b % d == 0){ x = (x* (b/d)) % N ; x = (x + N) % (N/d); mark = true; return x; } return -N; } int main(){ ll a,b,c,k; while (scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&k) && !(a==0 && b==0 && c==0 && k==0)){ N = (1LL<<k); b = (b-a+N ) % N; mark = false; ll ans = modular(c,b); if (!mark){ printf("FOREVER\n"); } else{ ll t = N / gcd; if (ans < 0){ ans = ans + t*((ans / t) + (ans % t == 0 ? 0 : 1)); } if (ans -t > 0){ ans = ans - t*(ans / t); } printf("%I64d\n",(ans+N) % N); } } return 0; }