Uva 10820 交表

题目链接: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 }
View Code
原文地址:https://www.cnblogs.com/TreeDream/p/6686682.html