uva10820 - Send a Table 欧拉函数

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

Problem A
Send a Table
Input:
Standard Input

Output: Standard Output

 

When participating inprogramming contests, you sometimes face the following problem: You know how tocalcutale the output for the given input values, but your algorithm is way tooslow to ever pass the time limit. However hard you try, you just can't discoverthe proper break-off conditions that would bring down the number of iterationsto within acceptable limits.

Now if the range of input values is not too big,there is a way out of this. Let your PC rattle for half an our and produce atable of answers for all possible input values, encode this table into aprogram, submit it to the judge, et voila: Accepted in 0.000 seconds! (Somewould argue that this is cheating, but remember: In love and programmingcontests everything is permitted).

Faced with this problem during one programmingcontest, Jimmy decided to apply such a 'technique'. But however hard he tried,he wasn't able to squeeze all his pre-calculated values into a program smallenough to pass the judge. The situation looked hopeless, until he discoveredthe following property regarding the answers: the answers where calculated fromtwo integers, but whenever the two input values had a common factor, the answercould be easily derived from the answer for which the input values were dividedby that factor. To put it in other words:

Say Jimmy had to calculate a function Answer(x,y) where x and y are both integers in the range [1, N].  When he knows Answer(x, y), he can easilyderive Answer(k*x, k*y), where k is any integer from it by applying some simplecalculations involving Answer(x, y) and k. For example if N=4, he only needs toknow the answers for 11 out of the 16 possible input value combinations:Answer(1, 1), Answer(1, 2), Answer(2, 1), Answer(1, 3), Answer(2, 3), Answer(3,2), Answer(3, 1), Answer(1, 4), Answer(3, 4), Answer(4, 3) and Answer(4, 1).The other 5 can be derived from them (Answer(2, 2), Answer(3, 3) and Answer(4,4) from Answer(1, 1), Answer(2, 4) from Answer(1, 2), and Answer(4, 2) fromAnswer(2, 1)). Note that the function Answer is not symmetric, so Answer(3, 2)can not be derived from Answer(2, 3).

Now what we want you to do is: for any values ofN from 1 upto and including 50000, give the number of function Jimmy has topre-calculate.

Input

The input file contains at most 600 lines ofinputs. Each line contains an integer less than 50001 which indicates the valueof N. Input is terminated by a line which contains a zero. This line should notbe processed.

 

Output

For eachline of input produce one line of output. This line contains an integer  which indicates how many values Jimmy has topre-calculate for a certain value of N.

 

 

 

 

SampleInput                              Output for Sample Input

2

5

0

 

3

19

 



  φ函数的值  通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数(小于等于1)就是1本身)。 (注意:每种质因数只一个。比如12=2*2*3。
若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。
设n为正整数,以 φ(n)表示不超过n且与n互
素的正整数的个数,称为n的欧拉函数值,这里函数
φ:N→N,n→φ(n)称为欧拉函数。
若m,n互质,φ(mn)=φ(m)φ(n)。
特殊性质:当n为奇数时,φ(2n)=φ(n)。

  以上这一段来自百度百科。

  打出欧拉公式的表也就比快速打素数表多出一步,找到素数p后把这个素数的倍数x都标记(如果x没有访问过,就先把phi[x]赋值为x),由于x有素因子p,所以要乘以(1-1/p),也就是除以p再乘(p-1)(注意最好是先除再乘,防止越界)。最后把小于等于要求值的素数都找一遍后,每个φ(x)就都求出来了。

  这道题求的是小于等于N的互素对数,所以打完表后要递推一下,phi[i]=phi[i-1]+phi[i],再就是一组两个数交换位置也算,所以答案要乘以2,(1,1)是特例,要再减去1。
 
 
#include<cstring>
#include<cstdio>
#include<iostream>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
int N,phi[50010],M=50010;
void phi_table(){
    memset(phi,0,sizeof(phi));
    int i,j;
    phi[1]=1;
    for(i=2;i<=M;i++) if(!phi[i]){
        for(j=i;j<=M;j+=i){
            if(!phi[j]) phi[j]=j;
            phi[j]=phi[j]/i*(i-1);
        }
    }
}
int main(){
    //freopen("in.txt","r",stdin);
    phi_table();
    int i;
    for(i=2;i<=M;i++) phi[i]=phi[i]+phi[i-1];
    while(scanf("%d",&N),N){
        printf("%d\n",phi[N]*2-1);
    }
    return 0;
}