uva11426 欧拉函数应用
2016-07-16 16:57
381 查看
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=121873#problem/F
题目大意:给你一个数n,让你输出(i=1->n-1)(j=i+1->n)gcd(i,j)
思路分析:直接暴力做铁定超时,而且数据也不止一组,因此我们要考虑打表来做这一道题, 既然要打表,就要
寻找递推关系,手写一下,比较容易就可以找到递推关系,S
=S[n-1]+f
f
=gcd(1,n)+gcd(2,n)+.......+gcd(n-1,n),现在问题就转化成了如何求f
,直接求目测超时,这一步就
比较奇妙,我们可以从约数开始入手,看约数为1.2.....分别有多少个数,数的个数刚好为phi[j/i]
代码:
题目大意:给你一个数n,让你输出(i=1->n-1)(j=i+1->n)gcd(i,j)
思路分析:直接暴力做铁定超时,而且数据也不止一组,因此我们要考虑打表来做这一道题, 既然要打表,就要
寻找递推关系,手写一下,比较容易就可以找到递推关系,S
=S[n-1]+f
f
=gcd(1,n)+gcd(2,n)+.......+gcd(n-1,n),现在问题就转化成了如何求f
,直接求目测超时,这一步就
比较奇妙,我们可以从约数开始入手,看约数为1.2.....分别有多少个数,数的个数刚好为phi[j/i]
代码:
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int maxn=4000000+100; ll phi[maxn]; ll prime[maxn/10]; ll s[maxn]; ll f[maxn]; bool check[maxn]; int tot; void make_phi() { phi[1]=1; memset(check,true,sizeof(check)); tot=0; for(ll i=2;i<maxn;i++) { if(check[i]) { prime[tot++]=i; phi[i]=i-1; } for(int j=0;j<tot&&i*prime[j]<=maxn;j++) { check[i*prime[j]]=false; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; } else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } } void init() { memset(f,0,sizeof(f)); for(int i=1;i<maxn;i++)//打表求f[i] { for(int j=2*i;j<=maxn;j+=i) { f[j]+=i*phi[j/i]; } } s[1]=0; for(ll i=2;i<maxn;i++) { s[i]=s[i-1]+f[i]; } } int main() { ll n; make_phi(); init(); while(scanf("%lld",&n)&&n) { printf("%lld\n",s ); } }
相关文章推荐
- 云计算的三种服务模式:IaaS,PaaS和SaaS
- opencv之离散傅里叶变换(DFT)
- 我的NIO学习笔记
- c++逐行读取写入txt文件的方法
- 【C语言基础】-03运算符
- 杂花生树(一)
- golang之cgo---类型转换小试牛刀之C结构体和go结构体转换
- C 语言操作符优先级和结合性
- 大话设计模式:抽象工厂模式
- 【记录】DAC
- APP开发实战91-静态Vector基础
- Javascript 定义命名空间,减少全局变量污染
- 设计模式之组合模式
- 数函间时++C
- SCU2016-06 S题 技巧性动态规划
- 【POJ 1279】Art Gallery
- poj 1088 记忆化搜索
- linux优化基础之更改“字符集”
- Android ImageView的scaleType属性与adjustViewBounds属性
- ARM体系中存储系统非对齐的存储访问操作