PKU2115

题目链接:http://poj.org/problem?id=2115

 更多介绍:http://blog.csdn.net/lhfight/article/details/7755994

/*
 * 题意不难理解,只是利用了 k位存储系统 的数据特性进行循环。
 *例如int型是16位的,那么int能保存2^16个数据,即最大数为65535(本题默认为无符号),
 *当循环使得i超过65535时,则i会返回0重新开始计数
 *如i=65534,当i+=3时,i=1
 *其实就是 i=(65534+3)%(2^16)=1
 *有了这些思想,设对于某组数据要循环x次结束,那么本题就很容易得到方程:
 *x=[(B-A+2^k)%2^k] /C
 *即 Cx=(B-A)(mod 2^k)  此方程为 模线性方程,本题就是求X的值。
 *令a=C   
 *b=B-A  
 *n=2^k
 *那么原模线性方程变形为:
 *ax=b (mod n)
 *该方程有解的充要条件为 gcd(a,n) | b ,即 b% gcd(a,n)==0
 *扩展的欧几里德
 *令d=gcd(a,n)
 *有该方程的 最小整数解为 x = e (mod n/d)
 *其中e = [x0 mod(n/d) + n/d] mod (n/d) ,x0为方程的最小解
 *那么原题就是要计算b% gcd(a,n)是否为0,若为0则计算最小整数解,否则输出FOREVER
 *当有解时,关键在于计算最大公约数 d=gcd(a,n) 与 最小解x0
 *参考《算法导论》,引入欧几里得扩展方程  d=ax+by ,
 *通过EXTENDED_EUCLID算法(P571)求得d、x、y值,其中返回的x就是最小解x0,求d的原理是辗转相除法(欧几里德算法)
 *再通过x0计算x值。注意x0可能为负,因此要先 + n/d 再模n/d。
 *注意:计算n=2^k时,用位运算是最快的,1<<k (1左移k位)就是2^k
 * */
import java.util.*;

public class PKU2115 {
	static long x,y;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A, B, C, K;
		while (sc.hasNext()) {
			A = sc.nextLong();
			B = sc.nextLong();
			C = sc.nextLong();
			K = sc.nextLong();
			if (A == 0 && B == 0 && C == 0 && K == 0)
				break;
			long n = 1L << K;// 移位运算,n=2^k
			long a = C;
			long b = B - A;
			x = y = 0;
			long gcd = extend_GCD(a, n);
			//System.out.println(gcd);
			if (b % gcd != 0)
				System.out.println("FOREVER");// 方程 ax=b(mod n) 无解
			else {
				x = (x * (b / gcd)) % n; // 方程ax=b(mod n)的最小解
				x = (x % (n / gcd) + n / gcd) % (n / gcd); // 方程ax=b(mod n)的最小整数小解
				System.out.println(x);

			}
		}
	}

	private static long extend_GCD(long a, long b) {
		if (b == 0) {
			x = 1;
			y = 0;
			return a;
		}
		long ret = extend_GCD(b, a % b);
		long t = x;
		x = y;
		y = t - a / b * y;
		return ret;
	}

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怎么演

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值