数论/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\n",i,getphi(i));
	while(1){
		int n=read();
		if(!n) break;
		printf("%d\n",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\n",i,phi[i]);printf("\n");
	while(1){
		int n=read();
		if(!n) break;
		ll ans=0;
		rep(i,2,n) ans+=phi[i];
		printf("%lld\n",ans);
	}
	return 0;
}

  

posted @ 2016-07-31 11:22  BBChq  阅读(168)  评论(0编辑  收藏  举报