数论基础
常用运算符
∑ a b c \sum_{a}^bc ∑abc:求和运算,读作sigma,一般的形式为 ∑ a b c \sum_{a}^bc ∑abc。其中a,b是两个表达式,分别表示开始条件和结束条件,c表示求和的式子,整个式子表示将所有符合条件的c求和。
∏ a b c \prod_{a}^bc ∏abc:求积运算,读作pi,和 ∑ \sum ∑使用方法相同,但是表示的是表达式之积。
[a]:其中a是一个表达式,当a不成立的时候,整个中括号的值为0,否则为1。
x|y:整除符号,表示x是y的因子,也就是y%x=0。
x mod y:取模符号,也就是%。
≡ \equiv ≡:同余符号,一般和 mod 一起出现, a ≡ b ( m o d p ) a\equiv b\pmod{p} a≡b(modp)表示表达式a,b在%p的意义下相等。
⌊ x ⌋ \left\lfloor x \right\rfloor ⌊x⌋:向下取整。
⌈ x ⌉ \left\lceil x\right\rceil ⌈x⌉:向上取整。
基本常识
素数/质数:除了1和本身之外没有其他因子的自然数。
gcd:最大公因数
lcm:最小公倍数
a%b ⟺ \Longleftrightarrow ⟺a - b ⌊ a b ⌋ \left\lfloor\dfrac{a}{b}\right\rfloor ⌊ba⌋
欧拉函数: ϕ \phi ϕ(x),表示[1,x - 1]之间与 x 互质的整数的个数。
乘法逆元:若ab ≡ \equiv ≡ 1 mod p则称a,b在模p意义下互为逆元,逆元存在的充要条件是gcd(a,p) = gcd(b,p) = 1,可以直接理解为取模意义下的 1 x \frac{1}{x} x1。
素数无限:素数是无限多的。
素数分布密度: π \pi π(n) lim n → ∞ π ( n ) l n n n \lim\limits_{n\to\infty}\dfrac{\pi(n)ln~n~}{n} n→∞limnπ(n)ln n = 1
调和级数: ∑ i = 1 n 1 i \sum_{i=1}^{n}\frac{1}{i} ∑i=1ni1 ~ O(log n)
埃氏筛复杂度: ∑ 1 p \sum\frac{1}{p} ∑p1 ~ O(log log n)
数论函数:定义域在整数域上的函数
积性函数:对于数论函数f,若对任意a,b满足gcd(a,b) ⟺ \Longleftrightarrow ⟺ f(a,b) = f(a)f(b)则称f是积性函数,对于积性函数有f(n) = ∏ \prod ∏ f(piei),可以用唯一分解求出积性函数的各函数值。
常用算法
埃氏筛
for(int i=2;i<maxn;++i)
{ for(int j=i*i;j<maxn;j+=i)
{
notPrime[j]=1;
}
}
线性筛
for(int i=2;i<maxn;++i)
{ if(!notPrime[i])
{
prime[tot++]=i;
f[i]=func();
g[i]=f[i];
}
for(int j=0;j<tot&&i*prime[j]<maxn;++j)
{
notPrime[i*prime[j]]=1;
if(i%prime[j]==0)
{
int ret = 1,x = i;
while(x%prime[j]==0)
{
ret*=prime[j];
x/=prime[j];
}
f[i*prime[j]]=f[i]/g[i]*f[ret];
g[i*prime[j]]=f[ret];
break;
}
f[i*prime[j]]=f[i]*f[prime[j]];
g[i*prime[j]]=f[prime[j]];
}
}
快速幂
int quickpow(int a,int n,int mod)
{
int ans = 1;
while(n)
{
if(n&1)
ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
辗转相除法/欧几里得算法
int gcd(int a,int b)
{
return b ? gcd(b, a % b) : a;
}
扩展欧几里得
int exgcd(int a,int b,int& x,int&y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int d = exgcd(b,a%b,x,y);
int tmp=x; x=y; y=tmp-y*(a/b);
return d;
}