右侧按钮可调深/浅色模式哦|

Hastieyua

园龄:6年1个月粉丝:68关注:3

扩欧讲解

                扩欧讲解

前记

       本蒟蒻的第二篇blog,之前学了扩欧却一直没时间写,现在趁着“山竹”台风,学校放假,写一下扩欧(qwq都忘得差不多了)

前提摘要

        what is 扩欧?

       扩欧及是扩展欧几里得,是欧几里得算法的扩展算法。

       欧几里得算法是蛤?就是小学学过的辗转相除法。用于计算两个整数a,b的最大公约数。代码:

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}

扩欧的基本问题:求解ax+by=c的所以整数解(a,b,c都为整数)

首先:要保证有整数解就必须有:gcd(a,b)|c.

证明:
gcd(a,b)|ax,gcd(a,b)|by gcd(a,b)|ax+by gcd(a,b)|c

然后,我们思考求ax+by=c的一组特解

扩欧讲解

代码:

int exgcd(int a, int b, int &x, int &y)
{
	if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int q = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return q;
}

线性同余方程

ax b (mod n)

换句话说:ax mod n = b mod n

性质: 满足同加性,同减性,同乘性,同幂性,但不满足同除性

那么 b mod n = b - nq (q为b除以n)

       ax mod n = ax - np (p为ax除以n)

       y=q-p

则 ax b (mod n)$ \ \ \ \ $ ax+ny=b

这样就转化成了扩欧啦。QAQ

洛谷【P1082同余方程】代码:

#include<cstdio> 
using namespace std;
long long a,b,x,y,k;
void gcd(int a,int b)
{
    if(b==0)
    {
        x=1;y=0;
        return;
    }
    gcd(b,a%b);
    k=x;x=y;y=k-a/b*y;
}
int main()
{
    scanf("%d%d",&a,&b);
    gcd(a,b);
    printf("%d",(x+b)%b);
    return 0;
}

求逆元

可用费马小定理和欧拉定理解决

扩欧方法:

可转化为 ax 1 (mod n),gcd(a,n)=1;

是不是看上去和同余方程很像。没错了,就是同余方程。

洛谷【P3811乘法逆元】代码:

#include<cstdio> 
using namespace std;
long long a,b,x,y,k;
void gcd(int a,int b)
{
    if(b==0)
    {
        x=1;y=0;
        return;
    }
    gcd(b,a%b);
    k=x;x=y;y=k-a/b*y;
}
int main()
{
    scanf("%d%d",&a,&b);
    gcd(a,b);
    for(int i=1;i<=a;i++){
    	gcd(i,b);
   		printf("%d\n",(x+b)%b);
   	}
    return 0;
}

后记

实话:本蒟蒻实在太菜,还有扩欧的一堆应用看不懂,如果大佬您强的话,可以看看





随便给点题

poj 青蛙的约会 P1516 青蛙的约会

NOIP2017day1,T1 小凯的疑惑

P1762 偶数

P4777 【模板】扩展中国剩余定理(EXCRT)

                 谢谢观赏,给个赞呗qwq

本文作者:Hastieyua

本文链接:https://www.cnblogs.com/hyfhaha/p/10678203.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Hastieyua  阅读(1672)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起