首页 > 代码库 > poj2115(扩展欧几里得运用)
poj2115(扩展欧几里得运用)
题意:求for(int i=a;i!=b;i+=c,i%=(1<<k))执行的次数;
解法:即求解C*x-(1<<k)*y=b-a;即C*x+K*y=b-a;如果g=gcd(C,K)不能被b-a整除,则说明无解。
用exgcd()求出一组C/g*x+K/g*y=1的解,然后两边乘上(b-a)/g将求出的x取最小正数输出。
代码:
/****************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 const double pi=acos(-1.0); typedef long long LL; const int Max=10100; const int INF=1000000007; LL A, B, C, k; LL exgcd(LL m,LL n,LL &x,LL &y)//求解方程mx+n*y=1的一组解(m,n已知,并且默认m,n互质)方程要灵活运用 { LL x1,y1,x0,y0; x0=1; y0=0; x1=0; y1=1; x=0; y=1; LL r=m%n; LL q=(m-r)/n; while(r) { x=x0-q*x1; y=y0-q*y1; x0=x1; y0=y1; x1=x; y1=y; m=n; n=r; r=m%n; q=(m-r)/n; } return n; } LL gcd(LL a,LL b) { return (a==0)?b:gcd(b%a,a); } int main() { while(cin>>A>>B>>C>>k) { if(A==0&&B==0&&C==0&&k==0) break; k=LL(1)<<k; LL x,y; LL g=gcd(C,k); if((B-A)%g!=0) { cout<<"FOREVER\n"; continue; } exgcd(C/g,k/g,x,y); k/=g; cout<<((x*(B-A)/g%k)+k)%k<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。