zoukankan      html  css  js  c++  java
  • 数论/the first wave

    线性筛素数(原来我之前学的不是线性的啊。。。

    void getprime(){
    	rep(i,2,nmax){
    		if(!vis[i]) prime[++prime[0]]=i;
    		for(int j=1;j<=prime[0]&&i*prime[j]<=nmax;j++){
    			vis[i*prime[j]]=true;
    			if(i%prime[j]==0) break;
    		}
    	}
    }
    

    利用了每个合数必有一个最小素因子,每个合数仅被它的最小素因子筛去正好一次,所以是线性时间。
    代码中体现在: if(i%prime[j]==0) break;(抄自M.J的blog

    求欧拉函数

    int getphi(int x){
    	int ans=x;
    	for(int i=2;i*i<=x;i++){
    		if(x%i==0) ans=ans/i*(i-1);
    		while(x%i==0) x/=i;
    	}
    	if(x!=1) ans=ans/x*(x-1);
    	return ans;
    }
    

    线性筛素数,欧拉函数。

    欧拉函数性质:f(ab)=f(a)f(b);

    void getphi(){
    	phi[1]=1;
    	rep(i,2,nmax){
    		if(!vis[i]) prime[++prime[0]]=i,phi[i]=i-1;
    		rep(j,1,prime[0]) {
    			int x=prime[j];
    			if(i*x>nmax) break;
    			vis[i*x]=true;
    			if(i%x==0){
    				phi[i*x]=phi[i]*x;break;
    			}else phi[i*x]=phi[i]*phi[x];
    		}
    	}
    }
    

    poj2407:求欧拉函数

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    int getphi(int x){
    	int ans=x;
    	for(int i=2;i*i<=x;i++){
    		if(x%i==0) ans=ans/i*(i-1);
    		while(x%i==0) x/=i;
    	}
    	if(x!=1) ans=ans/x*(x-1);
    	return ans;
    }
    int main(){
    	//rep(i,2,100) printf("%d:%d
    ",i,getphi(i));
    	while(1){
    		int n=read();
    		if(!n) break;
    		printf("%d
    ",getphi(n));
    	}
    	return 0;
    }
    

    poj2478:求欧拉函数前缀和

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define ll long long
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=1000005;
    int prime[nmax],phi[nmax];
    bool vis[nmax];
    void getphi(){
    	phi[1]=1;
    	rep(i,2,nmax){
    		if(!vis[i]) prime[++prime[0]]=i,phi[i]=i-1;
    		rep(j,1,prime[0]) {
    			int x=prime[j];
    			if(i*x>nmax) break;
    			vis[i*x]=true;
    			if(i%x==0){
    				phi[i*x]=phi[i]*x;break;
    			}else phi[i*x]=phi[i]*phi[x];
    		}
    	}
    }
    int main(){
    	getphi();
    	//rep(i,1,100) printf("%d:%d
    ",i,phi[i]);printf("
    ");
    	while(1){
    		int n=read();
    		if(!n) break;
    		ll ans=0;
    		rep(i,2,n) ans+=phi[i];
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    leetcode_697. 数组的度
    645. 错误的集合
    leetcode_448. 找到所有数组中消失的数字
    leetcode_628. 三个数的最大乘积
    leetcode_414. 第三大的数
    leetcode_495. 提莫攻击
    leetcode_485. 最大连续1的个数
    在 Mac、Linux、Windows 下Go交叉编译
    Goland基本操作
    etcd搭建及基本使用
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5722634.html
Copyright © 2011-2022 走看看