[BZOJ2705][SDOI2012]Longge的问题
2016-04-10 12:04
288 查看
[SDOI2012]Longge的问题
DescriptionLongge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
HINT
【数据范围】
对于60%的数据,0 < N<=2^16。
对于100%的数据,0 < N<=2^32。
Solution
∑i=1ngcd(i,n)\sum_{i=1}^{n}gcd(i,n)
=∑d|nd∑i=1n[gcd(i,n)==d]=\sum_{d|n}d\sum_{i=1}^{n}[gcd(i,n)==d]
=∑d|nd∑i=1nd[gcd(i,nd)==1]=\sum_{d|n}d\sum_{i=1}^{\frac{n}{d}}[gcd(i,\frac{n}{d})==1]
=∑d|nd∗ϕ(nd)=\sum_{d|n}d*\phi(\frac{n}{d})
Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; template<typename T>inline void read(T &x){ x=0;T f=1;char ch=getchar(); while(!isdigit(ch)) {if (ch=='-')f=-1; ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} x*=f; } const int MaxN=100000; ll n,tot,d[MaxN],ans=0; inline ll phi(ll n){ ll res=n; for(ll i=2;i*i<=n;i++){ if(n%i==0){res/=i;res*=(i-1);} while(n%i==0) n/=i; } if (n!=1) res/=n,res*=(n-1); return res; } int main(){ read(n); for(ll i=1;i*i<=n;i++){ if(n%i==0) d[++tot]=i,d[++tot]=n/i; if(i*i==n) tot--; } for(int i=1;i<=tot;i++) ans+=d[i]*phi(n/d[i]); printf("%lld\n",ans); return 0; }
相关文章推荐
- 我的博客是如何搭建的(github pages + HEXO + 域名绑定)
- 让Java程序运行sudo命令
- SLT的代码(当然不是我写的,今天不小心炸出来了,纪念一下)
- SAP的组织架构
- System.out和System.err的并发
- 深入理解 hash 函数、HashMap、LinkedHashMap、TreeMap
- LeetCode *** 38. Count and Say
- recycleView学习01
- KMP算法实现
- 2014年辛星Javascript解读第三节
- 在类中声明函数而不去定义编译通过
- 查找(一)史上最简单清晰的红黑树讲解
- qt实现多平台的二维码展示
- iOS开发数据库篇—FMDB简单介绍
- iOS开发数据库篇—FMDB数据库队列
- 一个合格的程序员应该读过哪些书
- 1289 - LCM from 1 to n
- bfs
- 在fragment中实现仿tab效果
- Html之表单标签