POJ 2115 C Looooops (拓展欧几里德及证明)

大前提你要知道 拓展欧几里得的算法函数

首先 一定存在整数对满足方程  ax+by=gcd(a,b)   这里gcd(a,b)是最大公约数

同gcd一样我们可以用递归定义exgcd

假设已经求得 bx’+(a%b)y’=gcd(a,b)

                        已知a%b=a-(a/b)*b        (为什么会这样 因为a/b取整)

                        带入得到

                       bx’+(a-(a/b)*b)y’=gcd(a,b)

                       ay’+b(x’-a(a/b)*y’)=gcd(a,b)

                       我们可以发现 令x’’=y’   y’’=x’-a(a/b)*y’

 这就是递归过程的一部分

最后当b=0时有

                      a*1+b*0=a=gcd(a,b)

拓展欧几里得代码:

long long ex_gcd(long long a,long long b,long long &x,long long &y)
{
	long long d=a;
	if(b!=0)
	{
	d=ex_gcd(b,a%b,y,x);
	y=y-(a/b)*x;}
	else
	{
		x=1;
		y=0;
	}
	return d;
}

然后这题  首先已知方程  (A+Cx)mod(2^k)=B

                  那么就知道  存在一个数y使得  (2^k)*y+B=A+Cx   成立(这个很容易一眼看出来  自己举个例子就秒懂了)

                  变形就得到  Cx-(2^k)*y=B-A

                  就转换成了可以带入的方程式

                  最后通过通过拓展欧几里得求得d、x、y值,其中返回的x就是最小解x0,求d的原理是辗转相除法(欧几里德算法)

                  再利用MODULAR-LINEAR-EQUATION-SOLVER算法通过x0计算x值。注意x0可能为负,因此要先 + b/d 再模b/d。

看代码:

 /*
 qq:1239198605
 ctgu_yyf
        */

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
long long ex_gcd(long long a,long long b,long long &x,long long &y)
{
	long long d=a;
	if(b!=0)
	{
	d=ex_gcd(b,a%b,y,x);
	y=y-(a/b)*x;}
	else
	{
		x=1;
		y=0;
	}
	return d;
}

int main()
{
   ios::sync_with_stdio(false);
   long long aa,bb,cc,dd;
   
   while(cin>>aa>>bb>>cc>>dd)
   {
   if(aa==0&&bb==0&&cc==0&&dd==0)
   break;
   
   //(aa+ccx)mod(2^dd)=bb;
   
   //(2^dd)y+bb=aa+ccx
   
   //ccx+(-(2^dd))y=bb-aa
   
   long long a,b,c,x,y;
   a=cc;
   c=bb-aa;
   
   
   b=(long long)1<<dd;
   
   if(c==0)
   {
   cout<<"0"<<endl;
   continue;
   }
  
   long long d=ex_gcd(a,b,x,y);
   
   if(c%d)
   {
   cout<<"FOREVER"<<endl;
   continue;
   }
   
   long long dm=b/d; 
   x=((x*c/d)%dm+dm)%dm;
   cout<<x<<endl;
   
   }
  
   
   
   
   
    


return 0;
}

猜你喜欢

转载自blog.csdn.net/k_koris/article/details/81604516