第四章数学知识(四)

本文介绍了如何使用容斥原理解决数论问题,通过举例说明了如何利用位运算高效求解多个集合的并集大小。此外,还探讨了博弈论中的Nim游戏,讲解了先手必胜和必败状态的判断条件,并引入了Mex运算在Nim游戏中的应用。
摘要由CSDN通过智能技术生成

1.容斥原理

在这里插入图片描述
例题:890. 能被整除的数
在这里插入图片描述
如果暴力枚举的话肯定会超时,用容斥原理做。
以样例为例:
定义集合:
S2:1—10中所有能被 2 整除的数,也就是 2 的倍数的集合 {2,4,6,8,10}
S3:1—10中所有能被 3 整除的数,也就是 3 的倍数的集合 {3,6,9}
我们要求的就是 |S2∪S3| = |S1| + |S2| - |S2 ∩S3| = 5 + 3 - 1 = 7
在这里插入图片描述
现在题目是 p1,p2,…,pm
那我们要求的就是:
|Sp1∪Sp2∪Sp3∪…∪Spm| = |S1| + |S2| +…+|Sm| - 所有两两集合的交 + 所有三三集合的交 - … (奇数个集合就是正号,偶数个就是负号)
这是 m 个集合的运算
这个怎么求呢?用位运算
i:1----2m -1,把 i 看做 m 位的二进制串,每一位上,0表示不选这个集合,1表示选这个集合。所以,每个 i 就代表了这 m 个集合的一种选法。

import java.util.Scanner;

public class Main {
   
	static int N = 20;
	static int n;
	static int m;
	static int[] p = new int[N];//存m个质数
	
	public static void main(String[] args) {
   
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		for(int i = 0;i < m;i++) p[i] = sc.nextInt();
		sc.close();
		
		int res = 0;
		for(int i = 1;i < 1 << m;i++) {
   
			int t = 1, cnt = 0;
			for(int j = 0;j < m;j++) {
   //取每一位
				if(((i >> j) & 1) == 1) {
   
					cnt++;
					if((long)t * p[j] > n) {
   
						t = -1;
						break;
					}
					t *= p[j];
				}
			}
			if(t != -1)<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值