题目链接:点击打开链接
题意描述:输入两个整数(1=<x,y<=n),由f(x,y)->f(x*k,y*k)(其中k为任意正整数),所以只需要保存f(x,y),其他的就不用保存了。输入(n<=50000),你的任务是最少需要保存多少个元素。如n=2时有3个(1,1),(1,2),(2,1). (2,2)可以由(1,1)得到,所以不需要记录
解题思路:分析题意我们可以发现,只要只需要保存所有互素(x,y)元素即可,由此我们可以借助欧拉函数,在O(nloglogn)的时间内解决问题
#include <cstdio>
#include <cmath>
#define MAXN 50001
using namespace std;
int ans[MAXN];
void phi_table(int n,int *phi){
for(int i=2;i<=n;i++) phi[i]=0;
phi[1]=1;
for(int i=2;i<=n;i++) if(!phi[i])
for(int j=i;j<=n;j+=i){
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
long long tp=1;
for(int i=2;i<=n;i++){
tp+=(phi[i]<<1);
phi[i]=tp;
}
}
int main(){
phi_table(50000,ans);
int n;
while(scanf("%d",&n)!=EOF&&n!=0){
printf("%d\n",ans[n]);
}
return 0;
}