我们丧心病狂的教练,给我们的本期作业,竟然是
数论
这对于一个数学很渣的小蒟蒻来说,太难了啊
所以开始努力学习数论....的gcd
写这篇blog的原因——洛谷P1082
0X00 需要知道的知识
0X01 定义
gcd:若自然数d同时是自然数a和b的约数,则称d是a和b的公约数。在所有a和b的公约数中最大的一个,称为a和b的最大公约数,计为gcd(a,b)
0X02 定理
证明见lyd《算法竞赛进阶指南》0x32 最大公约数
0X03 九章算术·更相减损术
0X04 欧几里得算法
这个很有用,敲黑板划重点!!
0X10 题解
0X11 题目
题目描述
求关于xx的同余方程 ax≡1(mod b) 的最小正整数解。
输入输出格式
输入格式:
一行,包含两个正整数 a,ba,b,用一个空格隔开。
输出格式:
一个正整数 x,即最小正整数解。输入数据保证一定有解。
输入输出样例
输入样例#1:
3 10
输出样例#1:
7
0X12 重要的转化
仔细的观察一下这个方程
ax≡1(mod b)
再看看这个东西
ax+by=1(y为负整数)
哇塞他们是等价的哎
也就是说我们只需要求出一组解使等式成立就行了。且慢,再看一眼题,要求是最小的正整数解,那么只要求出最小的正整数x就完成了
怎么求呢
0X13 EXGCD
扩欧算法出现了!
void exgcd(long long a, long long b)
{
//当前目的:求解 ax + by = gcd(a, b) 这么一个方程
if(b == 0) //a, b不断改变的过程中,b最终必然会成为0
{
//在 b = 0 时等式还要成立? 使 x = 1, y = 0 ,必然成立
x = 1;
y = 0;
return;
}
exgcd(b, a % b);//把下一层系数传进去(先求下一个方程的解 )
//现在我们已经拿到了下一个方程的解x, y
long long tx = x;//暂时存一下x,别丢了
x = y;
y = tx - a / b * y;
}
这就搞定了
//
// main.cpp
// Luogu
//
// Created by gengyf on 2019/5/7.
// Copyright © 2019 yifan Geng. All rights reserved.
//
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
//#include<bits/stdc++.h>
using namespace std;
long long a,b,x,y;
void exgcd(long xx,long yy){
if(yy==0){
x=1;y=0;return ;
}
exgcd(yy,xx%yy);
long long tx=x;
x=y;
y=tx-xx/yy*y;
}
int main(){
scanf("%lld%lld",&a,&b);
exgcd(a,b);
while(x<0){
x+=b;
x%=b;
}
printf("%lld\n",x);
}