题解 CF7C 【Line】
这题一看就是扩欧水题(注意没学过扩欧那肯定就不是了,学过扩欧其实就是模板题),将此算式转换为Ax+By=-C即可,注意补充几个知识点(这几个知识点看完后可以自己写写代码,如果实在写不出来再来看代码,毕竟模板题记住就行了,但是还要理解):
扩展欧几里得算法:对于整数a,b,必定存在整数对x,y满足ax+by=gcd(a, b)
扩展欧几里得算法应用
1.不定方程ax+by=c无解判定:如果c%d==0有解,否则无解
2.求解不定方程ax+by=c:先用扩欧求出ax’+by’= d =gcd(a,b)的一组解x'和y',则方程原来的一组解为 x=x'c/d,y=y'c/d,通解为x=x'c/d+kb/d,y=y'c/d-ka/d(k为任意整数)
3.解模线性方程:a ≡ b (mod n)的含义是a和b关于模n同余,即a mod n==b mod n,则ax-b=ny,移项得ax-ny=b,这恰好是一个二元一次不定方程,用2解决。
4.乘法逆元:ax ≡ 1 (mod n)的解x称为a关于模n的乘法逆元。若gcd(a,n)=1有唯一解,反之无解。注意:通过扩欧算出的不定方程有很多解,最终的逆元应该是(x%n+n)%n,也就是逆元的范围是[0,n-1]
5.改写算式:(a/b) mod p == (a(b的逆元) ) mod p==((a mod p)((b的逆元) mod p)) mod p
至于证明就不再给出,毕竟LX说过:“证明是数竞选手的事,我们信竞看看,然后用就好了(百度一大堆感兴趣可自行搜索)。”
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
long long kuoou(long long a,long long b,long long &x1,long long &y1)//地址符号注意
{
long long x2,y2;
if(b==0)
{
x1=1;
y1=0;
return a;
}
long long d=kuoou(b,a%b,x2,y2);
x1=y2;
y1=x2-a/b*y2;
return d;
}
int main()
{
long long a,b,c,x,y;
scanf("%lld%lld%lld",&a,&b,&c);
c=-c;
long long d=kuoou(a,b,x,y);//这里面的x,y只是当ax+by==gcd(a,b)时候的解,还要在下面进行转换
if(c%d!=0)
{
printf("-1");
return 0;
}
x=x*c/d;
y=y*c/d;//这两步
//如果不是随机解而是限制解怎么办呢(比如最小解)?
//那么我们就要用到循环并分类讨论,具体代码不在阐述
printf("%lld %lld",x,y);
return 0;
}