1. 程式人生 > >POJ 2115 C-Looooops | exgcd

POJ 2115 C-Looooops | exgcd

span type () int spa eve scanf while algo

題目

給出一個循環for(int i=A;i!=B;i+=C) 在mod (1<<k) 下是否可以退出循環

是,輸出時間,否輸出FORVEER


題解:

題意可以變換成 A+Cx=B (mod 1<<k)

去掉mod之後變成 Cx=(B-A)+(1<<K)*y 是否有整數解

令 a=C,b=(1<<K) c=B-A

轉化為ax+by=c的問題

exgcd即可

註意開longlong 要寫1LL<<k 輸出x最小正整數

 1 #include<cstdio>
 2 #include<algorithm>
 3
#include<cstring> 4 typedef long long ll; 5 using namespace std; 6 ll A,B,C,x,y,k,a,b,g,c; 7 ll exGcd(ll a,ll b,ll &x,ll &y) 8 { 9 if (b==0) return x=1,y=0,a; 10 ll r=exGcd(b,a%b,y,x); 11 y-=(a/b)*x; 12 return r; 13 } 14 int main() 15 { 16 while (scanf("%lld%lld%lld%lld
",&A,&B,&C,&k) && A+B+C+k!=0) 17 { 18 19 a=C; 20 b=(1LL<<k); 21 c=B-A; 22 g=exGcd(a,b,x,y); 23 if (c%g!=0) puts("FOREVER"); 24 else 25 { 26 b/=g; 27 c/=g; 28 x=(x%b*c%b+b)%b; 29 printf("%lld\n",x); 30 } 31 32
} 33 return 0; 34 }

POJ 2115 C-Looooops | exgcd