zoukankan      html  css  js  c++  java
  • 洛谷 P5656 【模板】二元一次不定方程 (exgcd)

    传送门


    解题思路

    先转化为:
    ax+by=gcd(a,b)
    exgcd板子,求出一组特解(x_0),(y_0)后,我们发现,可以将
    (x_0+frac{kb}{gcd(a,b)})
    (y_0-frac{ka}{gcd(a,b)})
    所以可以得出,x的最小正整数解为(((x-1)\%(b/gcd)+b/gcd)\%(b/gcd)+1)
    注意因为要求正整数而不是整数,所以x一开始要减1后面要加1。
    因为abc都大于零,所以只需看x取最小正整数解时y的正负就可以判断方程是否有正整数解,看y同理。

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    int T;
    long long x,y;
    int exgcd(long long a,long long b){
    	if(b==0){
    		x=1;
    		y=0;
    		return a;
    	}
    	int gcd=exgcd(b,a%b);
    	swap(x,y);
    	y=y-(a/b)*x;
    	return gcd;
    }
    int main(){
    	cin>>T;
    	while(T--){
    		long long a,b,c;
    		scanf("%lld%lld%lld",&a,&b,&c);
    		int gcd=exgcd(a,b);
    		if(c%gcd!=0){
    			printf("-1
    ");
    			continue;
    		}
    		x*=c/gcd;
    		y*=c/gcd;
    		long long minx=((x-1)%(b/gcd)+b/gcd)%(b/gcd)+1,maxy=(c-minx*a)/b;
    		long long miny=((y-1)%(a/gcd)+a/gcd)%(a/gcd)+1,maxx=(c-miny*b)/a;
    		if(maxy<=0){
    			printf("%lld %lld
    ",minx,miny);
    			continue;
    		}
    		printf("%lld %lld %lld %lld %lld
    ",(maxx-minx)/(b/gcd)+1,minx,miny,maxx,maxy);
    	}
    	return 0;
    }
    

    注意开long long。

  • 相关阅读:
    曲线与直线相切
    两函数切线
    导数+放缩
    选取拟合函数
    二分法求零点次数
    奇函数+方程的根与零点
    对数函数绝对值交点问题
    判断函数相等+判断反函数+判断周期函数
    已知分段函数零点个数求范围
    2020-05-03 助教一周小结(第十二周)
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14768833.html
Copyright © 2011-2022 走看看