zoukankan      html  css  js  c++  java
  • 线性筛法求质数分解、欧拉函数

    普通筛法的缺点是:对于n,它的质因子有p1,p2,p3,那么n会被划掉3次。
    线性筛法的核心思想是:对于n,它只被它的最小质因子p1划掉1次。

    线性筛法略加变形即可用来求质数分解和欧拉函数。
    求质数分解时,一种方案是对于每个数字n,存储它的全部质因子,这样有点浪费空间。
    另一种存储方案是,对于每个数字n,只存储它的最小质因子及其幂。至于其它质因子可以向前递推。这种方式节省空间。

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h> 
    using namespace std;
    const int maxn = 1000;
    bool isPrime[maxn];
    int prime[300], psize;//线性筛法必须用数组存储现有质数
    int euler[maxn];//每个数字的欧拉函数值
    //nex:每个数字的下一跳,mip:每个数字的最小质因子,ci:每个数字最小质因子的幂
    int nex[maxn], mip[maxn], ci[maxn];
    void init(){
    	memset(isPrime, 1, sizeof(isPrime));
    	psize = 0;
    	for (int i = 2; i < maxn; i++){
    		if (isPrime[i]){
    			prime[psize++] = i;
    			euler[i] = i - 1;
    			nex[i] = i;
    			mip[i] = i;
    			ci[i] = 1;
    		}
    		for (int j = 0; j < psize&&prime[j] * i < maxn; j++){
    			isPrime[i*prime[j]] = false;
    			mip[i*prime[j]] = prime[j];
    			if (i%prime[j] == 0){
    				//说明i中已经包含prime[j]
    				euler[i*prime[j]] = euler[i] * prime[j];
    				nex[i*prime[j]] = nex[i];
    				ci[i*prime[j]] = ci[i] + 1;
    				break;
    			}
    			else{
    				euler[i*prime[j]] = euler[i] * (prime[j] - 1);
    				ci[i*prime[j]] = 1;
    				nex[i*prime[j]] = i;
    			}
    		}
    	}
    }
    int main(){
    	init();
    	for (int i = 2; i < maxn; i++){
    		printf("%d euler=%d nex=%d ", i, euler[i], nex[i]);
    		for (int j = i;; j = nex[j]){
    			printf("%d^%d ", mip[j], ci[j]);
    			if (mip[j] == nex[j])break;
    		}
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    【坐在马桶上看算法】算法5:解密回文——栈
    【坐在马桶上看算法】算法4:队列——解密QQ号
    【坐在马桶上看算法】小哼买书
    python项目离线环境配置指南
    vis.js绘图库的一个BUG以及源码修正
    Python 访问soap服务
    一些教训
    Django 图片上传、存储与显示
    WAMP的一些配置修改
    Alpha阶段个人总结
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/6369010.html
Copyright © 2011-2022 走看看