打表

P2428 - 打表

Description

有一道比赛题目,输入两个整数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)。

Input

输入只有一行,一个整数n;

Output

输出也仅有一行,即表里元素的个数。

Sample Input

2

Sample Output

3

 

 

先固定一个x的值,那么能选的小于x的值的个数就是与x互质的数的个数,
就是欧拉函数,然后还有大于x的,乘以二就可以了。
 1 #include<set>
 2 #include<map>
 3 #include<queue>
 4 #include<stack>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<string>
 8 #include<vector>
 9 #include<cstdio>
10 #include<cstdlib>
11 #include<cstring>
12 #include<iostream>
13 #include<algorithm>
14 #define maxn 50010
15 #define LL long long
16 using namespace std;
17 bool bj[maxn];
18 int phi[maxn],su[maxn];
19 int main()
20 {
21   freopen("!.in","r",stdin);
22   freopen("!.out","w",stdout);
23   int n,num=0;scanf("%d",&n);
24   phi[0]=0,phi[1]=0;
25   for(int i=2;i<=n+1;i++){
26     if(bj[i]==0) su[++num]=i,phi[i]=i-1;
27     for(int j=1;j<=num;j++){
28       if(i*su[j]>n+1) break;
29       bj[i*su[j]]=1;
30       if(i%su[j]==0){
31     phi[i*su[j]]=phi[i]*su[j];
32     break;
33       }
34       if(i%su[j]!=0) phi[i*su[j]]=phi[i]*(su[j]-1);
35     }
36   }
37   LL ans=0;
38   for(int i=2;i<=n;i++)
39     ans+=phi[i]-1;
40   printf("%lld",ans*2+2*n-1);
41   return 0;
42 }

 

 
posted @ 2017-03-29 22:32  嘘丶  阅读(583)  评论(1编辑  收藏  举报