POJ 2115

和POJ 1061一样

要求最小解,就尽可能的把ax的值附到by上去,所以可以有ax=b*k+a*v(因为附到by上后必须仍上a*x的形式)。两边同除a就可得到结果。

但是,我们知道,(a,b)=1。所以k|a,也就是说,ans=(x%b+b)%b。后来加上b是为了防止负数。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

__int64 gcd(__int64 a,__int64 b){
	if(b==0) return a;
	return gcd(b,a%b);
}

void exgcd(__int64 a,__int64 b,__int64 &x,__int64 &y){
	if(b==0){
		x=1; y=0;
		return ;
	}
	exgcd(b,a%b,x,y);
	__int64 tmp=x;
	x=y;
	y=tmp-(a/b)*y;
}

int main(){
	__int64 A,B,C,k,a,b,c;
	__int64 x,y;
	while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k)&&A+B+C+k>0){
		k=1LL<<(k);
		if(A==B){
			printf("0\n"); continue;
		}
		__int64 tmp;
		a=C; b=k; c=B-A;
		tmp=gcd(a,b);
		if(c%tmp!=0){
			printf("FOREVER\n");
			continue;
		}
		a/=tmp; b/=tmp; c/=tmp;
		exgcd(a,b,x,y);
		x*=c;
		tmp=(x%b+b)%b;
		printf("%I64d\n",tmp);
	}
	return 0;
}

  

时间: 2024-10-06 00:57:32

POJ 2115的相关文章

POJ 2115 (模线性方程 -&gt; 扩展欧几里得)

题意: for(i=A ; i!=B ;i +=C)循环语句,问在k位操作系统中循环结束次数. 若在有则输出循环次数. 否则输出死循环. 存在这样的情况:i= 65533 :i<=2:i+= 4:时i = 2: 由模线性方程->扩展欧几里得 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using

POJ 2115 C Looooops(扩展欧几里得应用)

题目地址:POJ 2115 水题..公式很好推.最直接的公式就是a+n*c==b+m*2^k.然后可以变形为模线性方程的样子,就是 n*c+m*2^k==b-a.即求n*c==(b-a)mod(2^k)的最小解.(真搞不懂为什么训练的时候好多人把青蛙的约会都给做出来了,这题却一直做不出来.....这两道不都是推公式然后变形吗.....) 代码如下: #include <iostream> #include <cstdio> #include <string> #incl

POJ 2115 模线性方程 ax=b(mod n)

/* (x*c+a)%(2^k)==b →(x*c)%(2^k)==b-a 满足定理: 推论1:方程ax=b(mod n)对于未知量x有解,当且仅当gcd(a,n) | b. 推论2:方程ax=b(mod n)或者对模n有d个不同的解,其中d=gcd(a,n),或者无解. 定理1:设d=gcd(a,n),假定对整数x和y满足d=ax+by(比如用扩展Euclid算法求出的一组解). 如果d | b,则方程ax=b(mod n)有一个解x0满足x0=x*(b/d) mod n .特别的设e=x0+

poj 2115 (解单变元模线性方程)

http://poj.org/problem?id=2115 题意: 给出a,b,c,k,求x,使得(a+c*x)%(2^k)=b 限制: 0 <= a,b,c < 2^k; 1 <= k <= 32 思路: 拓展欧几里得单变元模线性方程 令 A=c;C=((b-a)%(2^k)+2^k)%(2^k);B=2^k 则这道题就化为Ax%n=B 对于Ax%B=C -> Ax+By=C -> d=Ext_gcd(A,B,x,y) //d其实为gcd(A,B) -> if

poj 2115 C Looooops (解模线性方程)

链接:poj 2115 题意:对于C语言的循环语句for(i=A ; i!=B ;i +=C), 问在k位存储系统中循环几次才会结束. 若在有限次内结束,则输出循环次数,否则输出死循环. 注:利用了 k位存储系统的数据特性进行循环(会溢出) 例如int型是16位的,那么int能保存2^16个数据, 即最大数为65535(本题默认为无符号), 当循环使得i超过65535时,则i会返回0重新开始计数 如i=65534,当i+=3时,i=1   即 i=(65534+3)%(2^16)=1 分析:设对

【POJ 2115】 C Looooops (扩展欧几里德)

[POJ 2115] C Looooops 输入四个数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的逆元了 跑一遍扩欧即可 注意要变换成求最小正解 普通扩欧只是求个解 至于扩欧--看了好久...

POJ 2115 C Looooops(模线性方程)

http://poj.org/problem?id=2115 题意: 给你一个变量,变量初始值a,终止值b,每循环一遍加c,问一共循环几遍终止,结果mod2^k.如果无法终止则输出FOREVER. 思路: 根据题意原题可化成c * x = b - a mod (2 ^ k),然后解这个模线性方程. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio>

POJ 2115 C Looooops(Exgcd)

[题目链接] http://poj.org/problem?id=2115 [题目大意] 求for (variable = A; variable != B; variable += C)的循环次数, 其中变量为k比特无符号整数. [题解] 题目等价于求解Cx=(B–A)(mod 2^k),利用扩展欧几里得算法可以求解该问题 [代码] #include <algorithm> #include <cstring> #include <cstdio> using name

POJ 2115 C Loooooops 扩展欧几里得

http://poj.org/problem?id=2115 题意:给出a,b,c<=1e9,k<=32 求出p 使得 (a+pc)mod2^k=ba+pc同余b(mod2^k) 2^kx=a+pc-b -> 2^kx-pc=a-b 利用exgcd求出x,p即可 最小正整数解x=x0+(k/d)*n 通解 任意解:x同余x0 mod(k/d) x0%(k/d)显然和x0同余(k/d)x=(x0%k/d+k/d)%mod 为最小正整数解 x0%k/d为正 x显然为最小正整数解 x0%k/d