POJ 2115 C Loooooops 扩展欧几里得

http://poj.org/problem?id=2115

题意:给出a,b,c<=1e9,k<=32 求出p 使得 (a+pc)mod2^k=b
a+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为负,x0%k/d+k/d显然与x0同余k/d 也为正数 所以为最小正整数解

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=2e5+20;
ll a,b,c,k;
ll x,y;
ll exgcd(ll a,ll b)
{
	ll d;
	if(b==0)
	{
		y=0,x=1;
		return a;
	}

	d=exgcd(b,a%b);
	ll t=y;
	y=x-a/b*y;
	x=t;
	return d;

}
int main()
{
	while(cin>>a>>b>>c>>k&&(a+b+c+k))
	{
		k=(ll)1ll<<k;
		ll d=exgcd(c,k);
		if((b-a)%d||(a!=b&&c==0))
			puts("FOREVER");
		else
		{
			//
			x=x*(b-a)/d;
			//x=x0+(k/d)*n 通解  任意解 x同余x0 mod(k/d) 

			//x0%(k/d)显然和x0同余(k/d)
			//现在要使x为最小正整数解 如果x0%k/d可能为正或者负 所以x=(x0%k/d+k/d)%mod 为最小正整数解
			ll t=k/d;
			x=(x%t+t)%t; //最小正整数解
			cout<<x<<endl;
		}
	}
	return 0;
}

  

时间: 2024-10-24 11:39:06

POJ 2115 C Loooooops 扩展欧几里得的相关文章

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 C Looooops(扩展欧几里得)

辗转相除法(欧几里得算法) 时间复杂度:在O(logmax(a, b))以内 int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); } 扩展欧几里得算法 时间复杂度和欧几里得算法相同 int extgcd(int a, int b, int& x, int& y) { int d = a; if (b != 0) { d = extgcd(b, a % b, y, x); y -= (a / b) * x;

POJ 2142 - The Balance [ 扩展欧几里得 ]

题意: 给定 a b n找到满足ax+by=n 的x,y 令|x|+|y|最小(等时令a|x|+b|y|最小) 分析: 算法一定是扩展欧几里得. 最小的时候一定是 x 是最小正值 或者 y 是最小正值 (简单的证明应该是分x,y 符号一正一负,和x,y符号都为正来考虑) 扩欧解的方程为 ax+by = gcd(a, b) 先简化问题,等价为扩欧求的是 a'x+b'y = 1 则原方程等价为 a'x+b'y = n' (a, b, n 全部除以gcd(a, b) ) 先解x为最小正值的时候 x =

POJ 2142:The Balance_扩展欧几里得(多组解)

先做出两个函数的图像,然后求|x|+|y|的最小值.|x|+|y|=|x0+b/d *t |+|y0-a/d *t| 这个关于t的函数的最小值应该在t零点附近(在斜率大的那条折线的零点附近,可以观察出来).以下三种情况中,函数最小值都应该出现在B点附近./* 对于不定整数方程xa+yb=c,若 c mod Gcd(a, b)=0,则该方程存在整数解,否则不存在整数解. 上面已经列出找一个整数解的方法,在找到x * a+y * b = Gcd(a, b)的一组解x0,y0后 ,/*x * a+y

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 (扩展欧几里得)

C Looooops Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19826   Accepted: 5299 Description A Compiler Mystery: We are given a C-language style for loop of type for (variable = A; variable != B; variable += C) statement; I.e., a loop w

扩展欧几里得定理——POJ 1061

对应POJ 题目:点击打开链接 青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 94409   Accepted: 17470 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得

POJ 1061 青蛙的约会 (扩展欧几里得)

原式 ax + by = c    =>  ax1 + by1 = gcd(a,b); a,b,c为任意整数,d = gcd(a,b),则  ax1 + by1 = d 的一组解是(x1,y1),c是gcd(a,b)的倍数时,其中的一组解为(x1*c/d,y1*c/d);c不是gcd(a,b)的倍数时,无解 青蛙的约会,就是一道例题 按照题意很容易列举出等式:(x+ms) - (y+ns) = k*l;  (k=1.....n)   变形到  扩展欧几里得公式  即可: #include <i

poj 1061(扩展欧几里得)

青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 90299   Accepted: 16412 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能