素数筛,欧拉算法知识点总结

唯一分解定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。  即 对于任一个正整数X(除了1)都有这样一个式子:X=\prod p1^{a1}\cdot p2^{a2}...\cdot pn^{an}      p是素因子,a是素因子的个数

    素数判断,根号n快速判断,我就不多说了

素数筛法:

朴素筛法 ( 复杂度nlog(n) ): 

int prim[maxn],cnt = 0; //存放素数并计数
bool flag[maxn]; 	// 0为质数 1非质数 
for(int i = 2; i <= n; i++){
	if(!flag[i]){
		prim[cnt++] = i;
		for(int j = i+i; j <=n; j += i) {  //将质数的倍数筛掉 
			flag[j] = 1;
		}
	}
} 

线性筛法  ( 复杂度O(n) ): 

int prim[maxn],cnt = 0; //存放素数并计数
bool flag[maxn]; 	// 0为质数 1非质数 
for(int i = 2; i <= n; i++){
	if(!flag[i]){
		prim[++cnt] = i;
	}
	for(int j = 1; j <= cnt; j++) {
		if(i * prim[j] > n)
			break;
		flag[i * prim[j]] == 1;
		if(i % prim[j] == 0)  //所得的积的最小质因子不由因子提供
			break; 
	}
} 

 

 

欧拉函数

     定义:在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目。eg. φ(8)=,4,因为1,3,5,7均和8互质。  φ(1)=1 φ(2)=1 φ(3)=2 φ(4)=2 φ(5)=4 φ(6)=2 φ(7)=6 φ(8)=4...

     通项公式:φ(x)= x\prod_{i=1}^{n}(1-\frac{1}{pi})

a与b互质即,

int gcd(int a,int b) {
	return !b ? a : gcd(b,a%b); 
}

性质:

1. 对于素数p,φ(p)=p-1

2.积性函数即对于两个互质数p,q,φ(pq)=φ(p)*φ(q)=(p-1)(q-1)。

3.若n是质数p的k次幂,φ(n)=p^{k}-p^{k-1}=p^{k}(1-1/p),因为除了p的倍数外,其他数都跟n互质    

故 :  相同素因子相乘      φ(p^{k})=φ(p^{k-1})*p 即 φ(n)=p^{k}-p^{k-1}=p^{k}(1-1/p)                                                                                  不同素因子相乘      φ(pq)=φ(p)*φ(q)

 

计算欧拉函数:

朴素算法

int oula(int n) {
	int rea = n;
	for(int i=2; i<=n; i++) {
		if(n%i == 0) {
			rea = rea-rea/i;
			do{
				n /= i;
			}while(n%i == 0);
		}
	}
	return rea;
}

优化算法:

int oula(int n) {
	int rea = n;
	for(int i=2; i*i<=n; i++){
		if(n%i == 0) {
			rea = rea - rea/i;
			do{
				n /= i;
			}while(n%i==0);	
		}
	}
	if(n>1)
		rea = rea - rea/n;
	return rea;
}

 

欧拉函数打表:

朴素欧拉打表(复杂度 O(nlog(n))):  //递推打表

void getphi() {
	int i,j;
	for(i=1; i<maxn; i++)
		p[i] = i;
	for(i=2; i<maxn; i++){
		if(p[i]==i){
			for(j=i; j<maxn; j+=i)
				p[j] = (p[j]/i) * (i-1);
		}
	}
}

欧拉线性筛打表(复杂度O(n)):

void getphi() {
	phi[1] = 1;  //存放欧拉数
	for(int i=2; i<=n; i++) {
		if(!flag[i]){ //flag判断是否为素数,如果是素数 
			prim[++cnt] = i; //prim存放素数 cnt计数
			phi[i] = i-1;  //素数的欧拉数是它本身 -1 
		}
		for(int j=1; j<=cnt; j++) {
			if(i*prim[j] > n)
				break;
			flag[i*prim[j]] = 1; //线性筛去素数
			if(i%prim[j]==0) { //如果是性质3的情况,相同素因子相乘 
				phi[i*prim[j]] = phi[i]*prim[j];
				break;
			} 
			phi[i*prim[j]] = phi[i]*phi[prim[j]]; //不同素因子相乘 
	} 
}

 

     过了两天回头再看才彻底通透,接下来就是补题了,zkw同学会迟到但一定会到的    /呲牙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值