Problem
对于任意正整数 ,试问 中,有多少正数与 互质?
Idea
考虑容斥原理,求互质的个数,可以用总个数 减去不互质的数字的个数。
求与 其不互质的数字,原理上就是求 的 的数量,考虑分解质因数判断。
先预处理 的质因数分解方案,即 。
记 表示 的欧拉函数,则根据容斥原理,有:
 总情况数 
减去所有单个质因子的情况:
加上所有两项之积:$+\frac n {P_1 P_2}+\frac n {P_1 P_3}+\dots+\frac n {P_2 P_3}+\dots+\frac n {P_{k-1} P_k} $
减去所有三项之积:
以此类推:
直到所有项之积:
#include<bits/stdc++.h>
using namespace std;
int eular(int n) {
	int res=n,tot=n;
	vector<int> v;
	for(int i=2;i*i<=n;++i) {
		if(n%i) continue;
		res=res*(i-1)/i;
		while(n%i==0) n/=i;
	}
	if(n) res=res*(n-1)/n;
	return res;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int TT;
	cin>>TT;
	while(TT--) {
		int n;
		cin>>n;
		cout<<eular(n)<<'\n';
	}
	return 0;
}
筛法求欧拉函数
使用埃氏筛辅助算出每个数的质因子,可以快速地 预处理出 中每个数的 。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+7;
ll el[N];
ll tot_eular(int n) {
	for(int i=1;i<=n;++i) el[i]=i;
	for(int i=2;i<=n;++i) {
		if(el[i]!=i) continue;
		for(int j=i;j<=n;j+=i)
			el[j]=el[j]*(i-1)/i;
	}
	ll res=0;
	for(int i=1;i<=n;++i) res+=el[i];
	//for(int i=1;i<=n;++i) cout<<el[i]<<' ';
	return res;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	cout<<tot_eular(n)<<'\n';
	return 0;
}
 
     
          
          
            