POJ 2115 C-Looooops | exgcd
题目
给出一个循环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 }