AcWing数学知识

数学知识

质数

试除法 O ( n ) O(\sqrt{n}) O(n )

public static boolean isPrime(int x) {
   
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i ++) {
   
        if (x % i == 0) return false;
    }
    return true;
}

分解质因数 O ( n ) O(\sqrt{n}) O(n )

public static void divide(int x) {
   
    for (int i = 2; i <= x / i; i ++) {
   
        if (x % i == 0) {
   
            int s = 0;
            while (x % i == 0) {
   
                x /= i;
                s ++;
            }
            System.out.println(i + " " + s);
        }
    }
    if (x > 1) System.out.println(x + " 1");
    System.out.println();
}

筛质数

// 埃氏筛法 $O(nloglogn)$
public static int getPrimes(int x) {
   
    for (int i = 2; i <= x; i ++) {
   
        if (!st[i]) {
   
            prime[++ cnt] = i;
            for (int j = i + i; j <= x; j += i) {
   
                st[j] = true;
            }
        }
    }
    return cnt;
}

// 线性筛法 $O(n)$, n = 1e7时比埃氏筛法快一倍
// 算法核心:x仅会被其最小质因子筛去
import java.util.*;

class Main {
   
    static final int N = 1000010;
    static int[] primes = new int[N];
    static boolean[] st = new boolean[N];
    static int cnt = 0;
    
    public static int getPrimes(int x) {
   
        for (int i = 2; i <= x; i ++) {
    // 循环遍历所有数
            if (!st[i]) {
   
                primes[cnt ++] = i;
            }
            for (int j = 0; primes[j] <= x / i; j ++) {
   
                // 对于任意一个合数x,假设pj为最小质因子,当i<x/pj时,pj*i一定会被筛掉
                st[primes[j] * i] = true;
                if (i % primes[j] == 0) break;
            	/*
            	1. i%pj == 0,pj一定为i的最小质因子,pj也一定为i*pj的最小质因子
            	2. i%pj != 0, pj一定小于i的所有质因子,所以pj也为pj*i的最小质因子
            	*/
            }
        }
        return cnt;
    }
    
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int res = getPrimes(n);
        System.out.println(res);
    }
}

约数

试除法求约数

1.jpg

class Main {
   
    
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        List<Integer> temp;
        while (n -- > 0) {
   
            int x = sc.nextInt();
            temp = getDivisors(x);
            for(int i : temp) {
   
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
    
    public static List<Integer> getDivisors(int n) {
   
        ArrayList<Integer> res = new ArrayList<Integer>();
        
        for (int i = 1; i <= n / i; i ++) {
   
            if (n % i == 0) {
   
                res.add(i);
                if (i != n / i) {
   
                    res.add(n / i);
                }
            }
        }
        
        Collections.sort(res);
        return res;
    }
}

约数个数

KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ N = &p_1^{\al…

import java.util.*;

class Main {
   
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);    
        int n = sc.nextInt();
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        long ans = 1;
        long mod = 1000000007;
        while (n -- > 0) {
   
            int x = sc.nextInt();
            for (int i = 2; i <= x / i; i ++) {
   
                while(x % i == 0) {
   
                    x /= i;
                    map.put(i, map.getOrDefault(i, 0) + 1);
                }
                
            }
            if (x > 1) {
   
                map.put(x, map.getOrDefault(x, 0) + 1);
            }
        }
        
        for (int i : map.values()) {
   
            ans = ans * (i + 1) % mod;    
        }
        System.out.println(ans);
    }
}

约数之和

N = p 1 c 1 × p 2 c 2 × . . . × p k c k 约 数 个 数 : ( c 1 + 1 ) × ( c 2 + 1 ) × . . . × ( c k + 1 ) 约 数 之 和 : ( p 1 0 + p 1 1 + . . . p 1 c 1 ) × . . . × ( p k 0 + p k 1 + . . . p k c k ) N = p_{1}^{c_1} \times p_{2}^{c_2} \times ... \times p_{k}^{c_k} \\ 约数个数:(c_1 + 1) \times (c_2 + 1) \times ... \times (c_k + 1) \\ 约数之和:({p_1}^0 + {p_1}^1 + ... {p_1}^{c_1}) \times ...\times ({p_k}^0 + {p_k}^1 + ... {p_k}^{c_k}) N=p1c1×p2c2×...×pkck(c1+1)×(c2+1)×...×(ck+1)(p10+p11+...p1c1)×...×(pk0+pk1+...pkck)

while (pow -- > 0) {
   
    temp = (temp * key + 1) % mod
}

t = t ∗ p + 1 t = t * p + 1 t=tp+1
t = 1 t = 1 t=1
t = p + 1 t = p + 1 t=p+1
t = p 2 + p + 1 t = p^2 + p + 1 t=p2+p+1
t = p 3 + p 2 + p + 1 t = p^3 + p^2 + p + 1 t=p3+p2+p+1
. . . ... ...
t = p p o w + p p o w − 1 + . . . + 1 t = p^{pow} + p^{pow - 1} + ... + 1 t=ppow+ppow1+...+1

import java.util.*;

class Main {
   
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        
        while (n -- > 0) {
   
            int x = sc.nextInt();
            for (int i = 2; i <= x / i; i ++) {
   
                while (x % i == 0) {
   
                    x /= i;
                    map.put(i, map.getOrDefault(i,0) + 1);
                }
            }
            if (x > 1) {
   
                map.put(x, map.getOrDefault(x, 0) + 1);
            }
        }
        
        long res = 1L;
        long mod = 1000000007L;
        for (int key : map.keySet()) {
   
            int pow = map.get(key);
            long temp = 1;
            for (int i = 0; i < pow; i ++) {
   
                temp = (temp * key + 1) % mod;
            }
            res = res * temp % mod;
        }
        
        System.out.println(res);
    }
}

最大公约数

a a a b b b的最大公约数,记为 g c d ( a , b ) {\rm gcd}( a,b) gcd(a,b) a a a b b b的最小公倍数,记为 l c m ( a , b ) {\rm lcm}(a,b) lcm(a,b)
∀ a , b ∈ N ,    g c d ( a , b ) ∗ l c m ( a , b ) = a ∗ b \forall a,b \in \mathbb{N}, \ \ {\rm gcd}(a,b)\ast {\rm lcm}(a,b) = a\ast b a,bN,  gcd(a,b)lcm(a,b)=ab

d = g c d ( a , b ) , a 0 = a / d , b 0 = b / d d={\rm gcd }(a,b),a_0=a/d,b_0=b/d d=gcd(a,b),a0=a/d,b0=b/d。根据最大公约数的定义,有 g c d ( a 0 , b 0 ) = 1 {\rm gcd}(a_0,b_0)=1 gcd(a0,b0)=1(反证法证明,假设 g c d ( a 0 , b 0 ) = x > 1 , y = a 0 / x , z = b 0 / x {\rm gcd}(a_0, b_0)=x > 1,y=a_0/x,z=b_0/x gcd(a0,b0)=x>1,y=a0/x,z=b0/x,则存在 d 0 = d ∗ x d_0=d\ast x d0=dx使得 y = a / d 0 , z = b / d 0 , d 0 = d ∗ x > d y=a/d_0,z=b/d_0,d_0=d\ast x>d y=a/d0,z=b/d0,d0=dx>d,与 d d d a , b a,b a,b的最大公因数相矛盾)。根据最下公倍数的定义,有 l c m ( a 0 , b 0 ) = a 0 ∗ b 0 {\rm lcm}(a_0,b_0) = a_0 \ast b_0 lcm(a0,b0)=a0b0
于是 l c m ( a , b ) = l c m ( a 0 ∗ d , b 0 ∗ d ) = l c m ( a 0 , b 0 ) ∗ d = a 0 ∗ b 0 ∗ d = a ∗ b / d {\rm lcm}(a,b)={\rm lcm}(a_0\ast d, b_0\ast d)={\rm lcm}(a_0,b_0)\ast d=a_0\ast b_0\ast d= a\ast b / d lcm(a,b)=lcm(a0d,b0d)=lcm(a0,b0)d=a0b0d=ab/d

更相减损术

∀ a , b ∈ N , a ≥ b \forall a,b \in \mathbb{N},a\ge b a,bN,ab,有 g c d ( a , b ) = g c d ( b , a − b ) = g c d ( a , a − b ) {\rm gcd}(a,b)={\rm gcd}(b,a-b)={\rm gcd}(a,a-b) gcd(a,b)=gcd(b,ab)=gcd(a,ab)

对于 a , b a,b a,b的任意公约数 d d d,因为 d ∣ a , d ∣ b d|a,d|b da,db,所以 d ∣ ( a − b ) d|(a-b) d(ab)。因此 d d d也是 b , a − b b, a-b b,ab的公约数。

欧几里得算法(辗转相除法)

∀ a , b ∈ N , b ≠ 0 ,       g c d ( a , b ) = g c d ( b , a   m o d   b ) \forall a,b \in \mathbb{N},b \ne 0, \ \ \ \ \ {\rm gcd}(a,b)={\rm gcd}(b, a\ {\rm mod}\ b) a,bN,b=0,     gcd(a,b)=gcd(b,a mod b)

a < b a<b a<b,则${\rm gcd}(b, a\ {\rm mod}\ b) = {\rm gcd} (b,a) = {\rm gcd}(a,b) , 命 题 成 立 若 ,命题成立 若 a\ge b , 不 妨 设 ,不妨设 a=q\ast b + r$,其中 0 ≤ r < b 0\le r<b 0r<b。显然 r = a   m o d   b r=a \ {\rm mod} \ b r=a mod b。对于 a , b a,b a,b的任意公约数 d d d,因为 d ∣ a , d ∣ q ∗ b d|a,d|q\ast b da,dqb,故 d ∣ ( a − q b ) d|(a-qb) d(aqb),即 d d d也是 b , r b,r b,r的公约数。反之亦成立。因此 a , b a,b a,b的公约数集合与 b , a   m o d   b b,a\ {\rm mod}\ b b,a mod b的公约数集合相同。
于是它们的最大公约数自然也相同。

任何数都可以整除 0 0 0,因此 b = 0 b=0 b=0时, g c d ( a , b ) = a {\rm gcd}(a,b) = a gcd(a,b)=a

import java.util.*;

class Main {
   
    static int n;
    
    public static int gcd(int a, int b) {
   
        return b != 0 ? gcd(b, a % b) : a;
    }
    
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        while (n -- > 0) {
   
            int a = sc.nextInt();
            int b = sc.nextInt();
            System.out.println(gcd(a, b));
        }
    }
}

欧拉函数

欧拉函数

欧拉函数
对于正整数 n n n,欧拉函数是小于或等于 n n n的正整数中与 n n n互质的数的数目,记作 φ ( n ) \varphi(n) φ(n) φ ( 1 ) = 1 \varphi(1) = 1 φ(1)=1

求n的欧拉值
首先, 欧拉函数是一个积性函数,当 m , n m, n m,n互质时, φ ( m n ) = φ ( m ) ∗ φ ( n ) \varphi(mn) = \varphi(m)\ast\varphi(n) φ(mn)=φ(m)φ(n)

据唯一分解定理知 n = p 1 a 1 ∗ p 2 a 2 ∗ . . . ∗ p x a x n = p_1^{a_1}\ast p_2^{a_2}\ast ... \ast p_x^{a_x} n=p1a1p2a2...pxax

因此 φ ( n ) = φ ( p 1 a 1 ) ∗ . . . ∗ φ ( p x a x ) \varphi(n) = \varphi(p_1^{a_1})\ast...\ast\varphi(p_x^{a_x}) φ(n)=φ(p1a1)...φ(pxax)

对于任意一项 φ ( p s a s ) = p s a s − p s a s − 1 \varphi(p_s^{a_s}) = p_s^{a_s} - p_s^{a_s-1} φ(psas)=psaspsas1

从定义出发 φ ( p s a s ) \varphi(p_s^{a_s}) φ(psas)等于小于或等于 p s a s p_s^{a_s} psas的正整数中与 p s a s p_s^{a_s} psas互质的数的数目

1 1 1 p s a s p_s^{a_s} psas中共有 p s a s p_s^{a_s} psas个数字

其中与 p s a s p_s^{a_s} psas不互质的有 p s , 2 p s , . . . , p s a s − 1 ∗ p s p_s,2p_s,...,p_s^{a_s-1}\ast p_s ps,2ps,...,psas1ps p s a s − 1 p_s^{a_s-1} psas1

所以 φ ( p s a s ) = p s a s − p s a s − 1 = p s a s ∗ ( 1 − 1 p s ) \varphi(p_s^{a_s}) = p_s^{a_s} - p_s^{a_s-1}=p_s^{a_s}\ast(1-\frac1{p_s}) φ(psas)=psaspsas1=

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值