uva11426GCD - Extreme (II)
2016-03-22 21:44
197 查看
链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18553
题意:给定多个n,求所有的gcd(i,j)之和{1<=i<j<=n}。
分析:因为每一次的gcd必然是j的因子,我们只要对每个j的因子计算贡献即可,比如当前的因子为x,x|j,那么对答案的贡献为phi(j/x)*x,phi()是欧拉函数。O(nlogn)
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=4000010; const int MAX=151; const int mod=100000000; const int MOD1=100000007; const int MOD2=100000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000009; const ll INF=10000000010; typedef double db; typedef unsigned long long ull; int f ,a ,q ; ll ans ,sum ; void deal(int n) { int i,j,k=0,w; for (i=1;i<=n;i++) f[i]=i; memset(q,0,sizeof(q)); for (i=2;i<=n;i++) { if (!q[i]) { a[++k]=i; } for (j=1;j<=k;j++) { if (a[j]*i>n) break ; q[a[j]*i]=1; if (i%a[j]==0) break ; } } for (i=1;i<=k;i++) for (j=a[i];j<=n;j+=a[i]) f[j]=f[j]/a[i]*(a[i]-1); memset(ans,0,sizeof(ans)); for (i=1;i<=n;i++) for (j=2*i;j<=n;j+=i) ans[j]+=f[j/i]*i; sum[0]=0; for (i=1;i<=n;i++) sum[i]=sum[i-1]+ans[i]; } int main() { int n; deal(4000000); while (scanf("%d", &n)&&n) printf("%lld\n", sum ); return 0; }
相关文章推荐
- 由退租想到的
- 机器学习中的特征工程总结一
- 2016 第七届蓝桥杯省赛B组第二题--生日蜡烛
- ubuntu14.04LTS丢失登录界面
- 子类不能从父类继承哪些?
- php安装及相关配置
- Windows平台Go调用DLL的坑(居然有这么多没听过的名词)
- 23种设计模式小结
- 重构第11天 使用策略代替Switch(Switch to Strategy)
- PAT (Advanced Level) Practise 1071 Speech Patterns (25)
- 【POJ3624】Charm Bracelet(01背包)
- 51 nod 1103 N的倍数(鸽巢原理)
- VS2010上编译opencv3.1.0的32位静态链接库(动态链接库)
- GWAS with plink
- 第5课 基础知识
- leetcode213. [DP]House Robber II
- RHCE7 搭建SAMBA服务实现目录网络共享
- 数据结构 串匹配 好难懂
- codevs 1966 乘法游戏
- MySQL的create table as 与 like区别(转)