版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/86534516
题目p2104
From Tyvj Guest☆【bzoj2705】Longge的问题
背景 Background
此系列问题为数论专题
具体参考博文
http://blog.csdn.net/chty2018/article/details/53432272
描述 Description
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出
输入格式 Input Format
一个整数,为N。
输出格式 Output Format
一个整数,为所求的答案。
样例输入 Sample Input
6
样例输出 Sample Output
15
时间限制 Time Limitation
1s
注释 Hint
【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。
来源 Source
sdoi2012 【bzoj2705】Longge的问题
题面,数据来自宋逸群
题解
题目挺短的,思路也很清晰,就是设
,
则
那么
,我们可以由
得到
那么
怎么求呢?
也可以用下面公式计算:
。
举个栗子,45有质因数3和5,那么
,所以问题接解决了。
当然我下面的代码没有采用这种方法算phi(n)
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;
static int f=1;
static char ch=getchar();
while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
ll n,m,ans;
inline ll phi(ll x)
{
ll sum=x;
for (ll i=2;i<=m;++i)
{
if (x%i==0)
sum=sum/i*(i-1);
while (x%i==0) x/=i;
}
if (x>1)
sum=sum/x*(x-1);
return sum;
}
int main()
{
read(n);
m=(ll)sqrt(n*1.0);
for (int i=1;i<=m;++i)
if (n%i==0)
{
ans+=i*phi(n/i);
if (i*i<n)
ans+=(n/i)*phi(i);
}
printf("%lld\n",ans);
return 0;
}