数论

\(\qquad\!\!\)数论是纯粹数学的分支之一,主要研究整数的性质。

  • 1、欧几里得(GCD):

\(\qquad\!\!\)例题:

\(\qquad\!\!\)给出两个正整数,求出两个数的 \(\gcd\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<bits/stdc++.h>
#define in inline
#define re register
using namespace std;
int a,b;
in int qread()
{
int x=0,y=1;
int ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
{
y=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*y;
}
in void qwrite(re int x)
{
if(x<0)
{
putchar('-');
qwrite(-x);
}
else
{
if(x>9)
{
qwrite(x/10);
}
putchar(x%10+'0');
}
return ;
}
in gcd(re int x,re int y)
{
return y?gcd(y,x%y):x;
}
int main()
{
a=qread();
b=qread();
qwrite(gcd(a,b));
putchar('\n');
return 0;
}
  • 2、拓展欧几里得(exGCD):

\(\qquad\!\!\)例题:

\(\qquad\!\!\)对于三个自然数 \(a,b,c\),求一组满足 \(ax+by=c\)\((x,y)\) 的整数解。

\(\qquad\!\!\)首先我们需要判断是否存在整数解,对于这个方程存在整数解的充要条件为 \(\gcd(a,b)|c\)

\(\qquad\!\!\)我们先把方程化为 \(ax+by=\gcd(a,b)\),最后求得的 \(x,y\) 再乘以\(c\) 除以 \(\gcd(a,b)\) 即可。

\(\qquad\!\!\)根据朴素欧几里得,我们可以通过这个方程推一下式子: \[ \begin{aligned} ax+by&=\gcd(a,b)\\ &=\gcd(b,a \bmod b)\\ &\Rightarrow bx+ (a \bmod b)y\\ &=bx+(a-\left\lfloor\dfrac{a}{b}\right\rfloor b)y\\ &=ay+b(x-\left\lfloor\dfrac{a}{b}\right\rfloor by) \end{aligned} \] \(\qquad\!\!\)不难发现此时 \(x\) 变成了 \(y\)\(y\) 变成了 \(x-\left\lfloor \dfrac{a}{b} \right\rfloor y\),利用这个性质,我们可以递归去求解 \((x,y)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include<bits/stdc++.h>
#define in inline
#define re register
using namespace std;
int a,b,c,r;
int x,y;
in int qread()
{
int x=0,y=1;
int ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
{
y=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*y;
}
in void qwrite(re int x)
{
if(x<0)
{
putchar('-');
qwrite(-x);
}
else
{
if(x>9)
{
qwrite(x/10);
}
putchar(x%10+'0');
}
return ;
}
in int gcd(re int x,re int y)
{
return y?gcd(y,x%y):x;
}
in void exgcd(re int a,re int b,re int &x,re int &y)
{
if(!b)
{
x=1;
y=0;
}
else
{
exgcd(b,a%b,y,x);
y-=a/b*x;
}
return ;
}
int main()
{
a=qread();
b=qread();
c=qread();
int r=gcd(a,b);
if(c%r)
{
qwrite(-1);
putchar(' ');
qwrite(-1);
putchar('\n');
return 0;
}
exgcd(a,b,x,y);
x=x*c/r;
y=y*c/r;
qwrite(x);
putchar(' ');
qwrite(y);
putchar('\n');
return 0;
}