• 【模板】二元一次不定方程(exgcd)


    (p1=frac{b}{d} p2=frac{a}{d})(思考一下如何证明)

    (x=x0+k*p1 \y=y0-k*p2\)

    这里的k是同一个数 (思考一下如何证明)

    需要注意的是把 (ax+by=d) 转化为 (ax+by=c) 时 p1和p2保持不变而不是翻倍 (思考一下如何证明)

    处理正整数解问题时

    x取最小正整数时,y会取到最大正整数

    y取最小正整数时,x会取到最大正整数

    x增大则y必然减小

    y增大则x必然减小

    统计解的个数时只需要根据这个原理看一下最多能放下多少组x或y即可

    #include<bits/stdc++.h>
    #define N 110000
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    #define ull unsigned long long
    using namespace std;
    inline ll read()
    {
    	char ch=0;
    	ll x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
    	return x*flag;
    }
    ll X,Y;
    ll exgcd(ll a,ll b)
    {
    	if(!b){X=1;Y=0;return a;}
    	ll d=exgcd(b,a%b);
    	ll t=X;X=Y;Y=t-(a/b)*Y;
    	return d;
    }
    void work()
    {
    	ll a=read(),b=read(),c=read();
    	ll d=exgcd(a,b),p1=b/d,p2=a/d,k=c/d;
    	if(c%d){printf("-1
    ");return;}
    	X*=k;Y*=k;X=(X%p1+p1)%p1;if(!X)X+=p1;Y=(c-a*X)/b;
    	if(X>0&&Y>0)
    	{
    		ll num,xmin,ymin,xmax,ymax;
    		num=(Y-1)/p2+1;
    		X=(X%p1+p1)%p1;if(!X)X+=p1;Y=(c-a*X)/b;xmin=X;ymax=Y;
    		Y=(Y%p2+p2)%p2;if(!Y)Y+=p2;X=(c-b*Y)/a;ymin=Y;xmax=X;
    		printf("%lld %lld %lld %lld %lld
    ",num,xmin,ymin,xmax,ymax);
    	}
    	else
    	{
    		ll xmin,ymin;
    		X=(X%p1+p1)%p1;if(!X)X+=p1;Y=(c-a*X)/b;xmin=X;
    		Y=(Y%p2+p2)%p2;if(!Y)Y+=p2;X=(c-b*Y)/a;ymin=Y;
    		printf("%lld %lld
    ",xmin,ymin);
    	}
    }
    int main()
    {
    	ll t=read();
    	for(ll i=1;i<=t;i++)work();
    	return 0;
    }
    
  • 相关阅读:
    JavaScript作用域
    原生JS判断作用域输出值
    用原生JS写九九乘法表
    用原生JS写冒泡排序及动画演示
    用原生JS写翻转数组
    用原生JS写星星直角三角形
    rabbitmq系列——(5 消息确认 -- 生产者 事务性消息)
    rabbitmq系列——(5 消息确认 -- 消费者 自动确认和手动确认)
    rabbitmq系列——(6 消息队列集群)
    docker 发布 dotnet3.1 web
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/13334359.html
Copyright © 2020-2023  润新知