算术基本定理+容斥定理

今天学习了算术基本定理和容斥定理, 内容偏难,留作以后查阅复习使用。

算术基本定理:

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

成有限个质数的乘积,并且在不计次序的情况下,这种分解方式是唯一的。

举例:60=2*2*3*5;

公式表示:N = p1^r1*p2^r2*p3^r3*...*pn^rn;
(p1 < p2 < p3 <...< pn & pi is prime number and ri >= 0)

质因子分解代码实现:


int prm[N],sz;// prm提前预处理 
map<int, int> f(int n){
	map<int, int> ans;
	for(int i = 0; i < sz && prm[i] * prm[i] <= n; i++){
		while(n % prm[i] == 0){
			ans[prm[i]]++;
			n /= prm[i];
		}
	}
	if(n != 1) ans[n] = 1; 
	return ans;
}

prm[N]为预打表处理,把需要范围内的素数打表。代码复杂度sqrt(n).

算术基本定理的应用:

1.求解数n的因子个数:

根据算术基本定理:N = p1^r1*p2^r2*p3^r3*...*pn^rn

扫描二维码关注公众号,回复: 2579806 查看本文章

设n%a==0,即a是n的因子之一;

也有a = p1^a1*p2^a2*p3^a3*...*pn^an

那么   0<=an<=r1;

所以因子个数 ans=(1 + r1) *(1 + r2) * (1 + r3) * ... * (1 + rn)

2.求数N的所有因子之和:

要求N的各因子之和

N = p1^r1*p2^r2*p3^r3*...*pn^rn

f(n)是积性函数,即f(a*b)=f(a)*f(b) a,b为素数;

设 f(n) = (p^(r+1) - 1) / (p - 1)

ans=(p1^(r1+1) - 1) / (p1- 1)*(p2^(r2+1) - 1) / (p2 - 1)*...*(pn^(rn+1) - 1) / (pn - 1)

3,在算术基本定理下看 GCD和LCM:

X=p1^x1*p2^x2*p3^x3*...*pn^xn

Y=p1^y1*p2^y2*p3^y3*...*pn^yn

GCD=P1^min(x1,y1)*P2^min(x2,y2)*P3^min(x3,y3)*...*Pn^min(xn,yn)

LCM=P1^max(x1,y1)*P2^max(x2,y2)*P3^max(x1,y1)*...*Pn^max(xn,yn)


容斥定理:

要计算几个集合并集的大小,我们要先将所有单个集合的大
小计算出来,然后减去所有两个集合相交的部分,再加回所
有三个集合相交的部分,再减去所有四个集合相交的部分,
依此类推,一直计算到所有集合相交的部分

若要求 AUBUC的面积  即 A+B+C-A∩B-A∩C-B∩C-A∩B∩C

二进制状态枚举;

int main(){
	n <= 20 1e6
	1e8
	
	int n = 3; 
	for(int i = 0; i < (1 << n); i++){ // 相当于枚举所有的情况 时间复杂度o(2^n*n) 
		
		for(int j = 0; j < n ;j++){
			printf("%d ", (i >> j )& 1);
		}
		
		puts("");
	}
	
	return 0;
}

容斥定理部分应用:

  • 对于一个数字来说,区间有多少数字是它的倍数
  • 发现有重叠部分
  • 用容斥定理
  • 假如当前枚举到的状态有两个数字a和b,那么区间中有多少
  • 个数字即是a的倍数也是b的倍数呢?

猜你喜欢

转载自blog.csdn.net/aimNO_1/article/details/81203775