输入四个数a b c k
一个循环for(a;;a += c) if(a == b) break;
a在k进制内循环 即0 <= a < 2^k 如果超了就返回0 即始终对2^k取余
可以得到一个方程 满足题意的话 a+c*x = b(mod 2^k)
即 c*x = b(mod 2^k) + a = (b+a)(mod 2^k) 同余
就变成求c跟2^k的逆元了 跑一遍扩欧即可 注意要变换成求最小正解 普通扩欧只是求个解
至于扩欧……看了好久。。。
http://blog.csdn.net/zhjchengfeng5/article/details/7786595
http://www.matrix67.com/blog/archives/5100
这俩博客挺不错的
代码如下:
#include <cstdio> using namespace std; #define ll long long ll e_gcd(ll a,ll b,ll &x,ll &y)//递归扩欧 { if(!b) { x = 1; y = 0; return a; } ll tmp, ans = e_gcd(b,a%b,x,y); tmp = x; x = y; y = tmp - a/b*y; return ans; } ll cal(ll a,ll m,ll c)//求逆元 { ll x,y,gcd; gcd = e_gcd(a,m,x,y); if(c%gcd != 0) return -1;//不可余说明方程无解 即为FOREVER x=(x*(c/gcd))%m; x=(x%(m/gcd)+m/gcd)%(m/gcd);//约分求最小解 return x; } int main() { int i,k; ll a,b,c,cnt; while(~scanf("%lld %lld %lld %d",&a,&b,&c,&k) && k) { cnt = cal(c,1LL<<k,b-a); if(cnt == -1) puts("FOREVER"); else printf("%lld\n",cnt); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-20 19:46:50