常用代码模板2——数学知识

将雪菜大佬的模板转写为java形式,C++见大佬原文AcWing @yxc

试除法判定质数

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

试除法分解质因数

void divide(int x) {
		for (int i = 2; i <= x / i; i++) {
			if (x % i == 0) {
				System.out.print(i + "*");
				x /= i;
				i--;
			}
		}
		System.out.println(x);
	}

朴素筛法求素数

	static int[] primes;	// primes[]存储所有素数
	static boolean[] st; // st[x]存储x是否被筛掉
	
	void get_primes(int n) {
		int cnt=0;
		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;
		}
	}

线性筛法求素数

	static int[] primes; // primes[]存储所有素数
	static boolean[] st; // st[x]存储x是否被筛掉

	void get_primes(int n) {
		int cnt = 0;
		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;
			}
		}
	}

试除法求所有约数


	ArrayList<Integer> get_divisors(int x)
	{
		ArrayList<Integer> res=new ArrayList<Integer>();
	    for (int i = 1; i <= x / i; i ++ )
	        if (x % i == 0)
	        {
	            res.add(i);
	            if (i != x / i) res.add(x / i);
	        }
	    return res;
	}

约数个数&约数之和

对于一个大于1正整数N可以分解质因数: N = p1^c1 * p2^c2 * … *pk^ck
如 100=2 * 2 * 5 * 5 = 22 * 52
约数个数: (c1 + 1) * (c2 + 1) * … * (ck + 1)
约数之和: (p1^0 + p1^1 + … + p1^c1) * … * (pk^0 + pk^1 + … + pk^ck)

欧几里得算法

//(最大公约数)
int gcd(int a, int b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

求欧拉函数

欧拉函数:小于或等于n的正整数中与n互质(公约数只有1)的数的数目

	int phi(int x) {
		int res = x;
		for (int i = 2; i <= x / i; i++)
			if (x % i == 0) {
				res = res / i * (i - 1);
				while (x % i == 0)
					x /= i;
			}
		if (x > 1)
			res = res / x * (x - 1);

		return res;
	}

筛法求欧拉函数

	static int[] primes; // primes[]存储所有素数
	static int[] euler; // 存储每个数的欧拉函数
	static boolean[] st; // st[x]存储x是否被筛掉

	void get_eulers(int n) {
		int cnt = 0;
		euler[1] = 1;
		for (int i = 2; i <= n; i++) {
			if (!st[i]) {
				primes[cnt++] = i;
				euler[i] = i - 1;
			}
			for (int j = 0; primes[j] <= n / i; j++) {
				int t = primes[j] * i;
				st[t] = true;
				if (i % primes[j] == 0) {
					euler[t] = euler[i] * primes[j];
					break;
				}
				euler[t] = euler[i] * (primes[j] - 1);
			}
		}
	}

扩展欧几里得算法

	static class Int {
		int v;
		public Int() {}
	}

	// 求x, y,使得ax + by = gcd(a, b)
	//c++可以利用指针交换值,java只能用内部类或者数组
	int exgcd(int a, int b, Int x, Int y) {
		if (b == 0) {
			x.v = 1;
			y.v = 0;
			return a;
		}
		int d = exgcd(b, a % b, y, x);
		y.v -= (a / b) * x.v;
		return d;
	}

递归法求组合数

	for (int i = 0; i < N; i++) {
		for (int j = 0; j <= i; j++) {
			if (j == 0)
				c[i][j] = 1;
			else
				c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
		}
	}
发布了41 篇原创文章 · 获赞 1 · 访问量 1417

猜你喜欢

转载自blog.csdn.net/qq_44467578/article/details/104395981