/*根据三条性质推导即可。
线性筛中每一个数字最多只会被筛一次,因此正好可以对每一个数字求欧拉函数。
线性筛正好是由小的数字筛到大的数字 or 正好是指数
前者用后两条性质 后者用第一条性质即可。
三条性质如下:
 1.如果n为某一素数的幂次,那么: φ(p^a)=(p-1)*p^(a-1)  (φ(p)=p-1) 
 2.如果i mod p=0,那么φ(i*p)=p*φ(i)
 3.如果i mod p≠0,那么φ(i*p)=φ(i)*(p-1)*/
#include <bits/stdc++.h>
using namespace std;
#define MAXN 10000000
bool f[MAXN+10];
int phi[MAXN+10],pri[MAXN+10],cnt; 
void Get_phi(int n)//欧拉筛 
{
	int i,j;
	phi[1]=1;
	for(i=2;i<=n;i++){//循环赋值 
		if(!(f[i])){//判断是否为素数 
			pri[++cnt]=i;//保存新筛素数 
			phi[i]=i-1;//欧拉筛性质1
		}
		for(j=1;j<=cnt&&i*pri[j]<=n;j++){
			f[i*pri[j]]=1;
			if(i%pri[j]==0) {//判断是否为i是否为已知素数的倍数 
				phi[i*pri[j]]=phi[i]*pri[j];//欧拉筛性质2
				break;
			}
			else phi[i*pri[j]]=phi[i]*(pri[j]-1);//欧拉筛性质3
		}
	}
 } 
 int main()
 {
 	int n;
 	scanf("%d",&n);
 	Get_phi(n);
 	printf("cnt:%d\n",cnt);
 	for(;n;n--)
 	{
 		printf("%d %d\n",n,phi[n]);
	 }
	 return 0;
 }

欧拉筛知识代码实现,今日份学习