题解 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;
}

posted @ 2018-02-24 12:48  最爱丁珰  阅读(36)  评论(0编辑  收藏  举报