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;
    }
    
  • 相关阅读:
    【26】多任务学习
    【25】迁移学习
    【24】定位数据不匹配
    【23】不匹配数据划分的偏差和方差;判断问题所在的几个重要参数
    【22】在不同的划分上进行训练和测试
    【21】进行误差分析
    17-----vue-cli脚手架安装和webpack-simple模板项目生成
    15-----修饰符
    14-----表单输入绑定
    12-----指令系统介绍
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/6369010.html
Copyright © 2011-2022 走看看