​第三届山西省程序设计大赛​

黑客大战
时间限制: C/C++ 1000ms; Java 2000ms 内存限制: 65535KB

问题描述
gscsdlz作为上兰帝国ACM的背后dalao,管理着上兰帝国ACM实验室的所有服务器,当然也是一名不为人知的传奇黑客,一天他又在测试实验室的OJ的安全性,突然发现有人正在对网站攻击,于是gscsdlz开始疯狂反击,在经历几分钟的交手之后,gscsdlz成功地打败了对方,对方当然不肯服输了,于是从OJ的主页找到了gscsdlz的联系方式,并向他发了一封email:
 虽然你在网络攻防上胜过了我,但在算法上我还是非常自信可以打败你的,当然,如果你能解决下面这道题目,我就认输。
 求一个正整数作为分母的绝对值小于1的最简分数的个数。
 gscsdlz作为常年隐蔽在ACM的dalao,当然会做了,于是他也回了一封email:你的题目太简单了,我不仅可以做出来,我还可以求所有分母小于等于n且绝对值小于的1最简分数的个数。
这当然涉及到黑客的知识盲区了,为了挽回颜面,他找到了身在上兰帝国的你,希望从内部获得答案。

输入描述
只有一个正整数n(1<=1000000)。
输出描述
输出一个数,表示所有分母小于等于n且绝对值小于1的最简分数的个数
样例输入
4
样例输出
10
提示
所有满足的最简分数有-3/4,-1/4,-2/3,-1/3,-1/2,1/2,1/3,2/3,1/4,3/4

这可能就是模板的力量的八,看题然想起来欧拉函数的意思,不就是求与n互质数的个数吗。模板一套差不多了,注意输出的ans超过了int的范围。

//1000000
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=1000000+10;
int euler[maxn+2];
void getEuler()
{
memset(euler,0,sizeof(euler)) ;
euler[1] =1;
for(int i=2;i<=maxn;i++)
{
if(!euler[i])
for(int j=i;j<=maxn;j+=i)
{
if(!euler[j])
euler[j]=j;
euler[j]=euler[j]/i*(i-1);
}
}
}
int main()
{
getEuler();
int n ;
ll ans=0;
//cout<<euler[5]<<endl;
scanf("%d",&n);
for(int i=2;i<=n;i++)
ans+=euler[i];
printf("%lld\n",2*ans);

//system("pause");
return 0;
}