数论--约数相关知识及代码实现


食用这篇文章前建议有素数相关的知识,若不了解的可以点开链接快速学习 数论 – 质数判定及其筛法求解

基本概念

  • 设 a 和 b 是两个整数,如果 d | a 且 d | b,则称 d 为 a 与 b 的 公约数 \color{Orange}公约数 公约数

  • 除 0 之外 ,任何整数只有有限个因子。因而两个不全为 0 的整数只有有限个公因子,其中最大的称作 最大公约数 \color{Orange}最大公约数 最大公约数

试除法求约数

  • 给定一个数 N ,求 [1 ,N ]的所有约数

注意 \color{yellow}注意 注意

n 为完全平方数的时候 s q r t ( n ) ∣ n ,但此时 s q r t ( n ) 和 n / s q r t ( n ) 只能算作一个约数,因为他俩相等。此算法时间复杂度为固定值 O ( √ n ) n为完全平方数的时候sqrt(n) | n,但此时sqrt(n)和n / sqrt(n)只能算作一个约数,因为他俩相等。此算法时间复杂度为固定值O(√n) n为完全平方数的时候sqrt(n)n,但此时sqrt(n)n/sqrt(n)只能算作一个约数,因为他俩相等。此算法时间复杂度为固定值O(n)

代码模板

vector<int> get_dividors(int x)
{
    vector<int> res;
    
    for(int i = 1; i <= x/i; i ++ )
        if(x % i == 0)
        {
            res.push_back(i);
            
            if(i != x / i) res.push_back(x / i); // 完全平方数只需要记 一个因子
        }
    
    sort(res.begin(), res.end()); // 排序
}

约数个数

算术基本定理 \color{Green}算术基本定理 算术基本定理

任何一个大于 1 的自然数 N, 如果 N 不为 质数,那么 N 可以 唯一分解成有限个质数的乘积

设 a > 1 ,则
a = p 1 α 1 ∗ p 2 α 2 ∗ ⋅ ⋅ ⋅ p k α k a = p_1^{α_1}*p_2^{α_2}*···p_k^{α_k} a=p1α1p2α2⋅⋅⋅pkαk
其中

p 1 ,   p 2 ,   ⋅ ⋅ ⋅ ⋅ ,   p k p_1,\ p_2,\ ····,\ p_k p1, p2, ⋅⋅⋅⋅, pk是不同的素数

α 1 ,   α 2 ,   ⋅ ⋅ ⋅ ⋅ ,   α k α_1,\ α_2,\ ····,\ α_k α1, α2, ⋅⋅⋅⋅, αk是正整数

并且在不记顺序的情况下,该表示是唯一的

约数个数定理 \color{SpringGreen}约数个数定理 约数个数定理

对于 N分解质因数 :
N = p 1 α 1 ∗ p 2 α 2 ∗ ⋅ ⋅ ⋅ p k α k N = p_1^{α_1}*p_2^{α_2}*···p_k^{α_k} N=p1α1p2α2⋅⋅⋅pkαk
由 约数定义 可知 ,对于 $ p_1^{α_1}$ 来说 ,它的约数 为
p 1 0 , p 1 1 ⋅ ⋅ ⋅ p 1 α 1 p_1^{0}, p_1^{1}···p_1^{α_1} p10p11⋅⋅⋅p1α1
( α 1 + 1 ) (\alpha_1 + 1) α1+1

同理 对于 N 其他的质因数来说 ,它们的约数 为 . . . ( α n + 1 ) ...(\alpha_n + 1) ...(αn+1)

故根据乘法原理可知:

N 的约数的个数为  ( α 1 + 1 ) ( α 2 + 1 ) ⋅ ⋅ ⋅ ( α n + 1 ) N 的 约数的个数为\ (\alpha_1 + 1)(\alpha_2 + 1)···(\alpha_n + 1) N的约数的个数为 (α1+1)(α2+1)⋅⋅⋅(αn+1)

代码模板

LL res ;
const long long mod = // 很大的一个数,用来保证答案在此范围
    
void get_primes(int x)
{
    for(int i = 2; i <= x/i ; i ++ )
        if(x % i == 0)
        {
            int s = 0;
            
            while(x % i == 0) s ++, x /= i; // 计算 质因子 的个数 即 某个 α
            
            res *= (LL) (s + 1) % mod; // N 的 约数的个数为 (α1 + 1)(α2 + 1)···(αn + 1)
        }
    
    if(x > 1) res *= (LL) (1 + 1) % mod;// x 若 最后为 大于 1 的质数,约数的个数为 1 
    
}

约数之和

约数和定理 \color{SpringGreen}约数和定理 约数和定理

对于 N 分解质因数 :
N = p 1 α 1 ∗ p 2 α 2 ∗ ⋅ ⋅ ⋅ p k α k N = p_1^{α_1}*p_2^{α_2}*···p_k^{α_k} N=p1α1p2α2⋅⋅⋅pkαk
由约数个数定理可知 N 的 正约数个数有
  ( α 1 + 1 ) ( α 2 + 1 ) ⋅ ⋅ ⋅ ( α n + 1 ) \ (\alpha_1 + 1)(\alpha_2 + 1)···(\alpha_n + 1)  (α1+1)(α2+1)⋅⋅⋅(αn+1)
那么 N 的 d(n)个正约数的和为
δ ( n ) = ( p 1 0 + p 2 1 + ⋅ ⋅ ⋅ p 1 α 1 ) ∗ ⋅ ⋅ ⋅ ∗ ( p n 0 + p n 1 + ⋅ ⋅ ⋅ p n α n ) δ(n) = (p_1^0 + p_2^1+···p_1^{\alpha1})*···*(p_n^0 + p_n^1+···p_n^{\alpha_n}) δ(n)=(p10+p21+⋅⋅⋅p1α1)⋅⋅⋅(pn0+pn1+⋅⋅⋅pnαn)

秦九韶算法 \color{Green}秦九韶算法 秦九韶算法

计算一元n次多项式:
f ( x ) = a n x n + a n − 1 x n − 1 + a n − 2 x n − 2 + . . . a 1 x 1 + c        = ( . . . ( a n x + a n − 1 x + a n − 2 ) x . . . + a 1 ) x + c f(x)= a_nx^n + a_{n-1}x^{n-1} + a_{n-2}x^{n-2} +... a_{1}x^{1}+ c\\\ \ \ \ \ \ =(...(a_nx + a_{n-1}x+ a_{n-2})x...+ a_1)x + c f(x)=anxn+an1xn1+an2xn2+...a1x1+c      =(...(anx+an1x+an2)x...+a1)x+c

秦九韶算法实现

秦九韶算法的实现只是一个模拟算法的过程。假设 a [ i ] a[ i ] a[i] 数组输入了从多项式在次数为$\ i\ $那项的系数,那么秦九韶算法的核心代码块就是:

LL a[i];
void  qjs()
{
    for(int i = n - 1; i >= 1; i -- )
        ans *= x, ans += a[i]; // 也可以写成 ans =(ans * x + a[i])
    
}

代码模板

LL get_sum(int a, int b) // a 为 p , b 为各种 α 
{
    
    LL t = 1 ;
    
    while(b --)
    {
        t = (t * a + 1) % mod;// 这里 x 为 p , a【i】 恒为 1 
    }
    
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值