题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1761
解题思路:
筛选法求欧拉函数
题意:输入n属于[1,50000],定义一个二元组(x,y),满足1<=x,y<=n , 且x和y互质 , 要求输出二元组的个数。注意(2,3),(3,2)算作两个答案,所以我们只要求出一组答案再乘以2即可
关键是怎么找出这个二元组,其实就是筛选法求欧拉函数
我们约定x<y且x与y互质,那么我们将y从1枚举到n,对于每个y,找出所有小于它并且与它互质的x的个数,这不就是求y的欧拉函数吗?而y从1到n,不就是求n以内所有数字的欧拉函数吗?
所以最后的答案,就是n以内每个数字的欧拉函数值的累加和*2-1,没什么减1,是因为一个特殊的数字1,1的欧拉函数值为1(它本身),在x2过程中算了两次(1,1)要减去一个。
欧拉函数的简介:
AC代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 50000; int phi[N+10]; int main(){ memset(phi,0,sizeof(phi)); phi[1] = 1; for(int i = 2; i <= N; i++){ if(!phi[i]){ for(int j = i; j <= N; j+=i){ if(!phi[j]) phi[j] = j; phi[j] = phi[j]/i*(i-1); } } } int n; while(scanf("%d",&n),n){ int ans = 0; for(int i = 1; i <= n; i++) ans += phi[i]; ans = 2*ans-1; printf("%d\n",ans); } return 0; }