算法之数学知识

一、质数

1.判断质数

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

2.分解质因数

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

3.筛质数

//朴素筛法
	import java.util.*;

	public class Main {
	static int cnt;
	static final int N = 1000010;
	static int[] primes = new int[N];
	static boolean[] st = new boolean[N];

	static void get_primes(int n) {
		for (int i = 2; i <= n; i++) {
			if (st[i])
				continue;
			primes[cnt++] = i;
			for (int j = i + i; j <= n; j += i) {
				st[j] = true;
			}
		}
	}
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		get_primes(n);
		System.out.println(cnt);
	}
}
//线性筛法
	static void get_primes(int n) {
		for (int i = 2; i <= n; i++) {
			if (!st[i]) {
				primes[cnt++] = i;
			}
			for (int j = 0; primes[j] <= n/i; j++) {
				st[primes[j] * i] = true;
				if (i % primes[j] == 0)
					break;
			}
		}
	}

二、约数

1.试除法求约数

	static void get_divisors(int n) {
		TreeSet<Integer> set = new TreeSet<>();
		for (int i = 1; i <= n / i; i++) {
			if (n % i == 0) {
				set.add(i);
				if (i != n / i) {
					set.add(n / i);
				}
			}
		}
		Iterator<Integer> it = set.iterator();
		while (it.hasNext()) {
			System.out.print(it.next() + " ");
		}
		System.out.println();
	}

2.约数个数

N=P1a1×P2a2×…×Pkak

约数个数 = (a1+1)(a2+1)…(ak+1)

约数之和 = (p10+p11+…+p1a1)(p20+p21+…+p2a2)…(pk0+pk1+…+pkak)

给定n个整数ai,输出这些数的乘积的约数个数

	import java.util.*;

	public class Main {

	static final int mod = (int) 1e9 + 7;

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

3.约数之和

给定n个整数ai,输入这些数的乘积的约数之和

	for (int key : map.values()) {
		int p = key, a = map.get(key);
		long t = 1;
		while ((a--) > 0) {
			t = (t * p + 1);//秦九韶算法
		}
		res = res * t % mod;
	}

4.最大公约数

//辗转相除法
	static int gcd(int p, int q) {
		return q != 0 ? gcd(q, p % q) : p;
	}

补充:秦九韶算法

f(x) = anxn+an-1xn-1+…+a1x+a0 = (…(anx+an-1)x+an-2)x+…+a1)x+a0

	static int f(int n, int a[], int x) {
		int p = a[n];
		for (int i = n-1; i >= 0; i--) {
			p = p * x + a[i];
		}
		return p;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值