<《模板》扩展欧几里德--求二元一次方程-及中国剩余定理>



扩展欧几里德----求二元一次方程:


1>  AX+BY=c;


2>   Bx+(A-A/B*B)y=c;


3>   化开--   Ay+Bx+A/B*By=c

即:   Ay+B(x-A/B*y)=c;

递归到 1 式  :  X=y ,    Y = x-A/B*y     .

推理结束---




注意:对于中国剩余定理-当a[0],,,,,a[n],,不是亮亮互素时,不能直接用中国剩余定理---只能两个先求--再合并-然后和下一个求--然后合并---直到所有的求完---

下面题有的是求最小数--有的是求区间中满足的个数--有的不让结果包含0


POJ 1061 青蛙的约会                    题目链接:点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL GCD(LL xx,LL yy)
{
    if (yy==0)
        return xx;
    return GCD(yy,xx%yy);
}
LL egcd(LL a,LL b,LL &xx,LL &yy)
{
    if (b==0)
    {
        yy=0;xx=1;
        return a;
    }
    LL p=egcd(b,a%b,xx,yy);
    LL t=xx;xx=yy;yy=t-a/b*yy;
    return p;
}
int main()
{
    LL v,s,x,y,m,n,l;
    while (~scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l))
    {
        v=n-m;s=x-y;
        /*if (s<0)
        {
            s=l-s;
        }
        if (v<0)
        {
            v=-v;
            s=l-s;
        }*/
        int gc=GCD(v,l);
        if (s%gc)
        {
            printf("Impossible\n");
            continue;
        }
        else
        {
            v/=gc;s/=gc;l/=gc;
            LL xx,yy;
            egcd(v,l,xx,yy);
            xx=(s*xx-(LL)(s*xx/l)*l);
            if (xx<0)
                xx+=l;
            printf("%lld\n",xx);
        }
    }
    return 0;
}


POJ 2891 Strange Way to Express Integers          题目链接:  点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL extend_gcd(LL a,LL b,LL &x,LL &y)
{
	if (b==0)
	{
		x=1;y=0;
		return a;
	}
	else
	{
		LL r=extend_gcd(b,a%b,y,x);
		y-=x*(a/b);
		return r;
	}
}
int main()
{
	LL n,a,b,xx,yy,r1,r2,ans;
	while (~scanf("%lld",&n))
	{
		scanf("%lld%lld",&a,&r1);
		bool fafe=true;
		for (int i=1;i<n;i++)
		{
			ans=0;
			scanf("%lld%lld",&b,&r2);
			if (fafe)
			{
				LL yu=extend_gcd(a,b,xx,yy);
				if ((r2-r1)%yu)
				{
					fafe=false;
				}
				else
				{
					b/=yu;
					xx=(xx*(r2-r1)/yu%b+b)%b;
					r1=xx*a+r1;
					a=b*a;
				}
			}
		}
		if (fafe)
		{
			r1=(r1%a+a)%a;//最简-- 
			printf("%lld\n",r1);
		}
		else
		printf("-1\n");
	}
	return 0;
}


POJ 1006 Biorhythms             题目链接:   点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int extend_gcd(int a,int b,int &x,int &y)
{
	if (b==0)
	{
		x=1;y=0;
		return a;
	}
	else
	{
		int r=extend_gcd(b,a%b,y,x);
		y-=x*(a/b);
		return r;
	}
}
int CRT (int a[],int m[],int n,int pp)
{
	int M=1;
	for (int i=0;i<n;i++) M*=m[i];
	int lp=0;
	for (int i=0;i<n;i++)
	{
		int x,y;
		int tm=M/m[i];
		extend_gcd(tm,m[i],x,y);
		lp=(lp+tm*x*a[i])%M;
	}
	int ans=((lp-pp)+M)%M;
	return ans? ans:M;
}
int main()
{
	int a[3],d,ca=1;
	int m[3]={23,28,33},n=3;
	while (scanf("%d%d%d%d",&a[0],&a[1],&a[2],&d),a[0]+a[1]+a[2]+d!=-4)
	{
		int p=CRT(a,m,n,d);
		printf("Case %d: the next triple peak occurs in %d days.\n",ca++,p);
	}
	return 0;
}


HDU 1573 X问题           题目链接:   点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL __int64
LL a[10000],r[10000];
LL extend_gcd(LL a,LL b,LL &x,LL &y){
	if (b==0)
	{
		x=1;y=0;
		return a;
	}
	else
	{
		LL r=extend_gcd(b,a%b,y,x);
		y-=x*(a/b);
		return r;
	}
}
int main()
{
	LL n,aa,b,xx,yy,r1,r2,chang,M;
	int t;scanf("%d",&t);
	while (t--)
	{
		scanf("%I64d%I64d",&chang,&n);
		for (int i=0;i<n;i++)
		scanf("%I64d",&a[i]);
		for (int i=0;i<n;i++)
		scanf("%I64d",&r[i]);
		bool fafe=true;
		aa=a[0];r1=r[0];
		for (int i=1;i<n;i++)
		{
			b=a[i];r2=r[i];
			if (fafe)
			{
				LL yu=extend_gcd(aa,b,xx,yy);
				if ((r2-r1)%yu)
				{
					fafe=false;
					break;
				}
				b/=yu;
				xx=(xx*((r2-r1)/yu)%b+b)%b;
				r1=xx*aa+r1;
				aa=b*aa;
			}
		}
		if (!fafe||chang<r1)
		printf("0\n");
		else
		{
			r1=(r1%aa+aa)%aa;
			LL ans=(chang-r1)/aa+1;
			if (r1==0) ans--;
			printf("%I64d\n",ans) ;
		}
	}
	return 0;
}


HDU 3579 Hello Kiki        题目链接:  点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL __int64
LL a[10000],r[10000];
LL extend_gcd(LL a,LL b,LL &x,LL &y)
{
    if (b==0)
    {
        x=1;y=0;
        return a;
    }
    else
    {
        LL r=extend_gcd(b,a%b,y,x);
        y-=x*(a/b);
        return r;
    }
}
int main()
{
    LL n,aa,b,xx,yy,r1,r2,chang,M;
    int t,ca=1;scanf("%d",&t);
    while (t--)
    {
        scanf("%I64d",&n);
        for (int i=0;i<n;i++)
        scanf("%I64d",&a[i]);
        for (int i=0;i<n;i++)
        scanf("%I64d",&r[i]);
        bool fafe=true;
        aa=a[0];r1=r[0];
        for (int i=1;i<n;i++)
        {
            b=a[i];r2=r[i];
            if (fafe)
            {
                LL yu=extend_gcd(aa,b,xx,yy);
                if ((r2-r1)%yu)
                {
                    fafe=false;
                    break;
                }
                else
                {
                    b/=yu;
                    xx=(xx*((r2-r1)/yu)%b+b)%b;
                    r1=xx*aa+r1;
                    aa=b*aa;
                }
            }
        }
        if (fafe)
        {
            r1=(r1%aa+aa)%aa;//最简-- 
            if (r1==0) r1=aa;
            printf("Case %d: %I64d\n",ca++,r1);
        }
        else
        printf("Case %d: -1\n",ca++);
    }
    return 0;
}


POJ 2115 C Looooops       题目链接:  点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL extend(LL a,LL b,LL &x,LL &y)
{
	if (b==0)
	{
		x=1;y=0;
		return a;
	}
	else
	{
		LL t=extend(b,a%b,y,x);
		y-=a/b*x;
		return t;
	}
}
int main()
{
	LL a,b,c,k,MOD;
	while (scanf("%lld%lld%lld%lld",&a,&b,&c,&k),a+b+c+k)
	{
		MOD=1;
		while (k--)
		MOD*=2;
		LL x,y;
		LL yu=extend(c,MOD,x,y);
		if ((b-a)%yu)
		{
			printf("FOREVER\n");
		}
		else
		{
			MOD/=yu;
			x=(x*(b-a)/yu%MOD+MOD)%MOD;
			printf("%lld\n",x);
		}
	}
	return 0;
}


HDU 1576 A/B        题目链接:   点击打开链接

代码“:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL __int64
LL extend(LL a,LL b,LL &x,LL &y)
{
	if (b==0)
	{
		x=1;y=0;
		return a;
	}
	else
	{
		int t=extend(b,a%b,y,x);
		y-=x*(a/b);
		return t;
	}
}
int main()
{
	int t;scanf("%d",&t);
	while (t--)
	{
		LL n,a,x,y,b=9973;
		scanf("%I64d%I64d",&n,&a);
		LL yu=extend(a,b,x,y);
		x=((x*n)%b+b)%b;
		printf("%I64d\n",x);
	}
	return 0;
}


HDU 2669 Romantic      题目链接:   点击打开链接

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
<span style="color:#cc33cc;">int gcd(int a,int b,int &x,int &y)
{
    if (b==0)
    {
        x=1;y=0;
        return a;
    }
    int r=gcd(b,a%b,x,y);
    int t=x;x=y;y=(t-a/b*y);
    return r;
}</span>
int main()
{
    int n,m,x,y;
    while (~scanf("%d%d",&n,&m))
    {
        int yu=gcd(n,m,x,y);
        if (yu!=1)
        {
            printf("sorry\n");
            continue;
        }
      //  printf("%d   %d  %d\n",yu,x,y);
        <span style="color:#3333ff;">if (x<0)
        {
            int xx=-x,ge;
            ge=xx/(m/yu);
            x+=ge*(m/yu);
            if (x<0)
            {
                x+=m/yu;
                ge++;
            }
            y-=ge*n;
        }</span>
        printf("%d %d\n",x,y);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值