数论知识整理
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论知识整理相关的知识,希望对你有一定的参考价值。
数论知识整理
1.整除
b|a,表示b整除a 或 a能被b整除,b%a=0
带余数除法:a,b为两个整数,存在q,r使a = bq + r,0<=r<b, 且q,r唯一
2.模运算
a mod b = a%b
取模运算的性质:加减乘
c++中,负数取模结果为负数,遵循使商尽可能大的原则
-5%3=-2,有时负数取模需要加上被除数使除数变为正数
除法取模:需要逆元
3.快速幂logn
4.gcd
gcd(a,b) = gcd(b,a%b)
gcd(a,b) = gcd(b,a-b)
lcm = a*b/gcd(a,b)
性质:
可重复性贡献:gcd(a,b,c) = gcd(gcd(a,b),c) lcm也一样
gcd(a,0) = a,gcd(a,b) = gcd(a,-b)
5.类欧几里得算法
6.扩展欧几里得算法exgcd
6.1 ax+by=gcd(a,b)
ax+by=gcd(a,b)一定存在 x 0 , y 0 x_0,y_0 x0,y0整数解
int exGcd(int a, int b, int &x, int &y) //x和y使用引用
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int g = exGcd(b, a%b, x, y); //递归计算exGcd(b,a%b)
int temp = x; //存放x的值
x = y;
y = temp - (a/b)*y; //更新y = x(old) - a/b*y(old)
return g; //g是gcd
}
定理1:
对
于
a
x
+
b
y
=
g
c
d
(
a
,
b
)
设
有
整
数
解
x
0
,
y
0
对于ax+by=gcd(a,b)设有整数解x_0,y_0
对于ax+by=gcd(a,b)设有整数解x0,y0
则 所 有 解 为 { x = x 0 + b g c d ( a , b ) ∗ k k ∈ Z y = y 0 − a g c d ( a , b ) ∗ k k ∈ Z 则所有解为\\begin{cases}x = x_0+\\frac{b}{gcd(a,b)}*k&k\\in Z \\\\y= y_0 -\\frac{a}{gcd(a,b)}*k&k\\in Z \\end{cases} 则所有解为{x=x0+gcd(a,b)b∗ky=y0−gcd(a,b)a∗kk∈Zk∈Z
6.2 ax+by=c
定理二:
ax+by=c有整数解的充要条件:gcd(a,b)|c,即gcd(a,c)可以整除c。
可以通过扩展欧几里得求解任意ax+by=c的方程解:
把ax+by=gcd(a,b) 等式两边同时乘上 c g c d ( a , b ) \\frac{c}{gcd(a,b)} gcd(a,b)c,方程变为 a ∗ c ∗ x g c d ( a , b ) + b ∗ c ∗ y g c d ( a , b ) = c a*\\frac{c*x}{gcd(a,b)}+b*\\frac{c*y}{gcd(a,b)}=c a∗gcd(a,b)c∗x+b∗gcd(a,b)c∗y=c
则其中 一 个 解 为 { x = x 0 ∗ c g c d ( a , b ) y = y 0 ∗ c g c d ( a , b ) 一个解为\\begin{cases}x = \\frac{x_0*c}{gcd(a,b)} \\\\y= \\frac{y_0*c}{gcd(a,b)} \\end{cases} 一个解为{x=gcd(a,b)x0∗cy=gcd(a,b)y0∗c,其中 x 0 , y 0 x_0,y_0 x0,y0是扩展欧几里得算法求解出来的 x 0 , y 0 x_0,y_0 x0,y0
7.同余和逆元
7.1. 同余
a和b模m同余,即 a ≡ b ( m o d m ) a≡b(mod\\space m) a≡b(mod m)
解同余方程: a x ≡ b ( m o d m ) ax≡b(mod \\space m) ax≡b(mod m)
可以这样理解:
ax是m的y倍再加上余数,即ax = my + b,移项得ax-my=b,因为y为整数,所以上式也等价于ax+my=b。
这就是欧几里得提到的方程组。
-
只有当gcd(a,m)能够整除b时才有解。
-
根据上面欧几里得的算法就可以求出一组解,对应的 x 0 x_0 x0即为一个解
7.2 逆元
求解 a x ≡ 1 ( m o d m ) ax≡1(mod \\space m) ax≡1(mod m),则求解出来的 x 0 x_0 x0称为a模m的逆,即为a的一个逆元。
- 等价于求解ax+my=1
求解出来的逆元可能是负数,最小的非负逆元即为 (m+x%m)%m
- 除法取模
假设b的逆元是k,有:
( a b ) m o d m = ( a k ) m o d m (\\frac{a}{b})mod\\ m=(ak)mod\\ m (ba)mod m=(ak)mod m
例题:
点击–>>题目链接
思路:需要知道前n项的平方和, S = n ( n + 1 ) ( 2 n + 1 ) 6 S=\\frac{n(n+1)(2n+1)}{6} S=6n(n+1)(2n+1),然后求6的逆元,最后龟速乘直接算出答案
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
ll x,y;
//龟速乘
ll mul(ll a,ll b)
{
ll res = 0;
while(b)
{
if(b&1) res = (res+a)%mod;
b >>= 1;
a = a*2%mod;
}
return res;
}
//求逆元
ll exgcd(ll a,ll b)
{
if(b==0)
{
x = 1;
y = 0;
return a;
}
ll g = exgcd(b,a%b);
ll temp = x;
x = y;
y = temp - (a/b)*y;
return g;
}
int main()
{
exgcd(6,mod);
x = (x%mod+mod)%mod;//6最小的非负整数逆元
ll n;
while(cin>>n)
cout<<mul(mul(mul(n,n+1),2*n+1),x)<<'\\n';
return 0;
}
以上是关于数论知识整理的主要内容,如果未能解决你的问题,请参考以下文章