[51nod1040]最大公约数之和
2016-07-06 15:31
295 查看
Description
求∑i=1ngcd(i,n)n<=10^9
Solution
这道题有多种做法。我们设f(n)=∑ni=1gcd(i,n)
那么f应该是积性函数。(证明自行脑补)
也就是说我们要求出来f(pk)p是质数
直接推式子似乎很麻烦,我们换个思路。
如何从f(pk)转移到f(pk+1)?
首先,因为我们可以把f(p^k)*p,那么就构成了f(p^k+1)的答案中所有不为1的部分.
(显然gcd(i,p)=gcd(i∗p,p2)∗p)
那么剩下的为1的就是φ(pk+1)了。
于是我们得到了f(pk+1)=f(pk)∗p+φ(pk+1)
于是就解决了。
然而,我发现似乎只有我一个人想用积性函数的方法。
其余的都是机智的直接φ法。
因为我们的答案都是n的因数。那么我们把它分解质因数,枚举每个因数x,我们就是要求1~n有多少个数k满足gcd(x,k)=x很显然有φ(nx)个。
于是暴力求φ也可以。
Code
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long ll; ll ans; int a[32],b[32],n; int main() { scanf("%d",&n);int i=2;ans=1; fo(i,2,sqrt(n)) { if (!(n%i)) a[++a[0]]=i; while (!(n%i)) b[a[0]]++,n/=i; } if (n>1) a[++a[0]]=n,b[a[0]]=1; fo(i,1,a[0]) { ll sum=1,x=1; fo(j,1,b[i]) sum=sum*a[i]+x*(a[i]-1),x*=a[i]; ans*=sum; } printf("%lld",ans); }
相关文章推荐
- 如何使用JavaScript调用android原生代码,android原生代码调用JavaScript
- 写给互联网创业的年轻人
- eclispe报错PermGen space
- Linux的内存回收和交换
- java加解密
- WEB开发文件上传存储,虚拟路径配置问题。
- unlink函数
- 在unity中用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放
- SpringMVC 数据校验
- 救援模式下解决linux开机失败
- 在Linux环境下搭建Java Web测试环境
- Forge的使用和养号教程
- 理解Java对象序列化
- file_put_contents() 图片保存 函数成功之后返回值
- mysql数据库 删除重复项 保留ts最新的项
- 常用效果集合
- Codeforces Round #360 (Div. 1) C. The Values You Can Make(DP)
- 自定义动态切换字符的TextView
- 嵌入式程序设计中C/C++代码的优化
- linux redhat配置yum源为网易(163)源的方法 (