打表
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 }