UVa 10820 - Send a Table(欧拉函数)

时间:2021-08-19 19:10:13

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1761

 

题意:

有一道比赛题目,输入两个整数x、y(1≤x,y≤n),输出某个函数f(x,y)。
有位选手想交表(即事先计算出所有的f(x,y),写在源代码里),但表太大了,源代码超过了比赛限制,需要精简。
那道题目有一个性质,即很容易根据f(x,y)算出f(x*k, y*k)(k是任意正整数),这样有一些f(x,y)就不需要保存了。
输入n(n≤50000),你的任务是统计最简的表里有多少个元素。例如,n=2时有3个:(1,1), (1,2), (2,1)。

 

分析:

本题的本质是:输入n,有多少个二元组(x,y)满足:1≤x,y≤n,且x和y互素。
不难发现除了(1,1)之外,其他二元组(x,y)中的x和y都不相等。设满足x<y的二元组有f(n)个,那么答案就是2f(n)+1。
对照欧拉函数的定义,可以得到f(n)=phi(2)+phi(3)+…+phi(n)。

 

代码:

 1 import java.io.*;
 2 import java.util.*;
 3 
 4 public class Main {
 5     static final int UP = 50000;
 6     static int phi[] = new int[UP+5];
 7     
 8     static void constant() {
 9         for(int t = 2; t <= UP; t++) if(phi[t] == 0) {
10             for(int i = t; i <= UP; i += t) {
11                 if(phi[i] == 0) phi[i] = i;
12                 phi[i] = phi[i] / t * (t-1);
13             }
14         }
15         for(int i = 3; i <= UP; i++) phi[i] += phi[i-1];
16     }
17     
18     public static void main(String args[]) {
19         Scanner cin = new Scanner(new BufferedInputStream(System.in));
20         constant();
21         
22         while(true) {
23             int n = cin.nextInt();
24             if(n == 0) break;
25             System.out.println(2 * phi[n] + 1);
26         }
27         cin.close();
28     }
29 }