题目链接:https://uva.onlinejudge.org/external/108/10820.pdf
题意:
对于两个整数 x,y,输出一个函数f(x,y),有个选手想交表,但是,表太大,需要精简;已知:f(x,y) 可以算出 f(x*k,y*k),所以有一些 f(x,y)可以不在表里。
给定一个 n,1<=x,y<=n,求最少的 f(x,y)个数。
设:
可以看出 x,y互素;
而且,和欧拉函数有一个特别的位置是,对角线,当x>1时,小于等于 x 的与 x 互素的数肯定没有 x,所以可以放心大胆的用欧拉函数。
注意的是,f(1,1)只有一个。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int euler_phi(int n) 6 { 7 int res = n; 8 for(int i=2; i*i<=n; i++) 9 { 10 if(n%i==0) 11 { 12 n/=i; 13 res = res - res / i; 14 while(n%i==0) 15 { 16 n/=i; 17 } 18 } 19 } 20 if(n>1) res = res - res / n; 21 return res; 22 } 23 int sum[50010]; 24 25 void phi_table(int n,int* phi) 26 { 27 for(int i=2; i<=n; i++) 28 phi[i] = 0; 29 phi[1]=1; 30 for(int i=2; i<=n; i++) 31 if(!phi[i]) 32 for(int j=i; j<=n; j+=i) 33 { 34 if(!phi[j]) 35 phi[j]=j; 36 phi[j]=phi[j]/i*(i-1); 37 } 38 sum[0] = 0; 39 for(int i=1; i<=50005; i++) 40 sum[i] = sum[i-1] + phi[i]; 41 } 42 43 int main() 44 { 45 int n; 46 int phi[50010]; 47 48 phi_table(50005,phi); 49 while(scanf("%d",&n),n) 50 { 51 printf("%d ",sum[n]*2-1); 52 } 53 return 0; 54 }