不定方程详解

橙三吉。 提交于 2020-02-08 17:42:42

二元一次不定方程

定义:abca,b,c是整数,ab0ab≠0,那么形如ax+by=cax+by=c的方程称为二元一次不定方程。
定理:设aba,b是整数,且d=(a,b)d=(a,b),如果dcd|c,那么方程存在无数多个整数解,否则方程不存在整数解。((a,b)=gcd(a,b))((a,b)=gcd(a,b))
二元一次不定方程和同余方程之间可以相互转换的,例如在a>0,b>0a>0,b>0的条件下,求解二元一次不定方程ax+by=cax+by=c与求解同余方程axc(mod b)ax≡c(mod\ b)是相同的。
求解同余方程使用扩展欧几里得算法,二元一次不定方程同样可以使用扩展欧几里得算法。
由扩展欧几里得可知:设aabb不全为0,则存在整数xyx,y,使得:
       gcd(a,b)=ax+bygcd(a,b)=ax+by
所以当dcd|c时,ax+by=cax+by=c存在整数解。
通过扩展欧几里得算法求出特解x0,y0x_0,y_0,那么通解为x0+n×bd,y0n×ad (nZ)x_0+n\times\frac{b}{d},y_0-n\times\frac{a}{d}\ (n∈Z).

void exgcd(int a,int b,int&d,int&x,int&y)//扩展欧几里得算法
{
    if(b==0)
    {
        x=1,y=0;
        d=a;
    }
    else 
    {
        exgcd(b,a%b,d,x,y); 
        int t=x;
        x=y;
        y=t-a/b*y ;
    }
}

nn元一次不定方程

定理:nn元一次不定方程a1x1+a2x2+...+anxn=c(a1,a2,...,an,cN)a_1x_1+a_2x_2+...+a_nx_n=c(a_1,a_2,...,a_n,c∈N),有解的充分必要条件是(a1,a2,...,an)c(a_1,a_2,...,a_n)|c.
nn元一次不定方程可以转化为求二元一次不定方程,nn元一次不定方程a1x1+a2x2+...+anxn=ca_1x_1+a_2x_2+...+a_nx_n=c,可以转为为下面形式:
S{a1x1+a2x2=d1t1d1t1+a3x3=d2t2d2t2+a4x4=d3t3    .    .    .dn1tn1+anxn=c S\left\{ \begin{aligned} &a_1x_1+a_2x_2=d_1t_1&\\ &d_1t_1+a_3x_3=d_2t_2&\\ &d_2t_2+a_4x_4=d_3t_3&\\ &\ \ \ \ .&\\ &\ \ \ \ .&\\ &\ \ \ \ .&\\ &d_{n-1}t_{n-1}+a_nx_n=c&\\ \end{aligned} \right.
(dn1,an)=(a1,a2,...,an)(d_{n-1},an)=(a_1,a_2,...,a_n),所以上述定理成立。
求出最后一个方程的解,然后代入倒数第二个方程,依此类推可以求出方程的所有解。
对于mmnn元一次不定方程组成的方程组,其中m<nm<n,可以消去m1m-1个未知数,从而消去m1m-1个不定方程,将方程组转化为一个nm+1n-m+1元的一次不定方程。然后依照nn元一次不定方程求解。

解不定方程简单应用

The Balance(poj 2142)

有一天平,两个质量为aabb的砝码,数量不限,且两边都可以放,要求称出质量为cc的物品,即两边平衡。尽量少的使用砝码,当砝码数量相同时总重量最小。
输入为abca,b,c.
思路:如果a小于b交换a,b。显然可以构造不定方程ax+by=cax+by=c,此时xxyy不一定为正整数,可以先求出一组特解x0,y0x_0,y_0,通解就为x0+n×bd,y0+n×ad (nZ)x_0+n\times\frac{b}{d},y_0+n\times\frac{a}{d}\ (n∈Z).因为要求砝码数尽量少,即min(x+y)min(|x|+|y|),代入通解为min(x0+n×bd+y0n×ad)min(|x_0+n\times\frac{b}{d}|+|y_0-n\times\frac{a}{d}|),因为a>ba>b,显然最小值应在y0da\frac{y_0d}{a}附近,可以for循环枚举前后的几个值,然后取min(x+y)min(|x|+|y|),当min(x+y)min(|x|+|y|)相等时min(ax+by)min(a|x|+b|y|)
代码如下:

#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;
const int maxx=1e6+7;
void exgcd(ll a,ll b,ll&d,ll&x,ll&y)
{
	if(!b)
	{
		x=1,y=0;
		d=a;
	}
	else
	{
		exgcd(b,a%b,d,x,y);
		ll temp=x;
		x=y;
		y=temp-a/b*y;
	}
}
int main()
{
    ll a,b,c,d,x0,y0;
	ios::sync_with_stdio(false);
	while(cin>>a>>b>>c&&(a||b||c))
	{
	    ll x=0x3f3f3f3f,y=0x3f3f3f3f,flag=0;
	    if(a<b) {swap(a,b);flag=1;}
		exgcd(a,b,d,x0,y0);
        a=a/d;
        b=b/d;
        x0=x0*c/d;
        y0=y0*c/d;
        for(ll i=y0/a-10;i<=y0/a+10;i++)
        {
            ll q=x0+i*b,p=y0-i*a;
            q=q<0?(-q):q; p=p<0?(-p):p;
            if(q+p<x+y)
                x=q,y=p;
            else if(q+p==x+y&&(q*a+p*b)<(x*a+y*b))
                    x=q,y=p;
        }
        if(!flag)
        cout<<x<<" "<<y<<endl;
        else cout<<y<<" "<<x<<endl;
    }
}

跳骚(poj 1091)

Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。
比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。
当确定N和M后,显然一共有M^N张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。
输入两个整数N和M(N <= 15 , M <= 100000000)。

思路:假设卡片上面数字为a1a2,...an,Ma_1,a_2,...a_n,M,跳骚选择卡片的次数为x1,x2,...xn,xn+1x_1,x_2,...x_n,x_{n+1},那么有不定方程a1x1+a2x2+...+anxn+Mxn+1=1a_1x_1+a_2x_2+...+a_nx_n+Mx_{n+1}=1,即(a1,a2,...,an,M)=1(a_1,a_2,...,a_n,M)=1,可以计算出(a1,a2,...,an,M)1(a_1,a_2,...,a_n,M)≠1的所有情况,然后用MnM^n减去即可。计算(a1,a2,...,an,M)1(a_1,a_2,...,a_n,M)≠1的所有情况可以使用容斥定理计算,如果gcd不等于1的话,那么这些数肯定都至少有一个M的质因子,假设d是M的一个质因子,那么小于M的可以整除d的数个数量就是Md\frac{M}{d}个,从其中任选n个,因为可以重复选择,所以数量就是Mdn\frac{M}{d}^n
所以ans=i=1rMdin (rM)ans=\bigcup\limits_{i=1}^{r}\frac{M}{d_i}^n\ (r为M的质因子数量)
由容斥原理可知:
i=1nSi=CMn(1)size(C)1TCT\left|\bigcup\limits_{i=1}^{n}S_i\right|=\sum\limits_{C\subseteq M}^{n}(-1)^{size(C)-1}\left|\bigcap\limits_{T\subseteq C}T\right|

#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;
const int maxx=1e6+7;
ll n,m,p[35],cnt,sum,ans;
ll qpow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
void dfs(int now,int id,int over,ll product)
{
    if(now==over)
    {
        sum+=qpow(m/product,n);
        return;
    }
    for(int i=id;i<=cnt;i++)
    {
        dfs(now+1,i+1,over,product*p[i]);
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>n>>m;
    ll a=m;
    for(int i=2;i*i<=a;i++)
        if(a%i==0)
        {
            p[++cnt]=i;
            while(a%i==0)
                a/=i;
        }
    if(a>1) p[++cnt]=a;
    for(int i=1;i<=cnt;i++)
    {
        sum=0;
        dfs(0,1,i,1);
        if(i&1)
            ans+=sum;
        else ans-=sum;
    }
    cout<<qpow(m,n)-ans<<endl;
}

特殊的不定方程

  1. 毕达哥拉斯定理:平面上的一个直角三角形中,两个直角边边长的平方加起来等于斜边长的平方。如果设直角三角形的两条直角边长度分别是aabb,斜边长度是cc,那么可以用数学语言表达:a2+b2=c2a^2+b^2=c^2.
    满足上面这个方程的正整数三元组被称为毕达哥拉斯三元组。
    如果一个毕达哥拉斯三元组xyzx,y,z,满足(x,y,z)=1(x,y,z)=1,那么这个毕达哥拉斯三元组被称为本原的毕达哥拉斯三元组。
    定理:正整数abca,b,c构成一个本原毕达哥拉斯三元组且y为偶数,当且仅当存在互质的正整数mnm>nm,n(m>n)其中mm为奇数,nn为偶数;或者nn为奇数,mm为偶数,并且满足:

    1. a=m2+n2a=m^2+n^2
    2. b=2mnb=2mn
    3. c=m2n2c=m^2-n^2
  2. 费马大定理:方程xn+yn=znx^n+y^n=z^n无非0整数解,其中nn为整数且n3n≥3.

  3. 佩尔方程:形如x2dy2=1x^2-dy^2=1(d>1d>1且不为完全平方数)的不定方程称为佩尔方程。
    佩尔方程当dd为完全平方数时,(x+dy)(xdy)=1(x+\sqrt{d}y)(x-\sqrt{d}y)=1,显然方程无解。
    解佩尔方程:
    若佩尔方程最小特解是(x_1,y_1),那么可有迭代公式:
    xn=xn1x1+dyn1y1x_n=x_{n-1}x_1+dy_{n-1}y_1
    yn=xn1y1+yn1x1y_n=x_{n-1}y_1+y_{n-1}x_1
    即:
    [xkyk]=[x1dy1y1x1]k[x1y1]\begin{bmatrix} x_k\\ y_k\\ \end{bmatrix}={\begin{bmatrix} x_1&dy_1\\ y_1&x_1\\ \end{bmatrix}}^k\begin{bmatrix} x_1\\ y_1\\ \end{bmatrix}
    我们可以通过矩阵快速幂求出第k个解。
    对于特解可以暴力求解:
    x2dy2=1x^2-dy^2=1,得x2=dy2+1x^2=dy^2+1,即x=dy2+1x=\sqrt{dy^2+1},那么令y=1y=1,代入求解xx,然后判断是否满足,否则就y=y+1y=y+1,直到求出满足的特解。

void find()
{
	int x,y=1;
	while(1)
	{
			x=(long long)sqrt(d*y*y+1);
			if(x*x-d*y*y==1)
				break;
			y++;
	}
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!