GCD
来源:互联网 发布:sql导入access数据库 编辑:程序博客网 时间:2024/06/05 21:04
题目来源:https://vjudge.net/problem/UVA-11426
【题意】
求在1-n之间所有任意两个数的的最大公因数的和。
【思路】
做完这道题,依旧感觉头脑懵懵的,看了好多篇博客方才看懂了这道题的解法,因为之前做过几道数论题,关于素数的比较多,这到题因为最大公因数就自然而然的想到了素数筛法,一直在找所谓的规律。最后终于崩溃了。。。
便搜了博客慰藉我不安的心灵,但是很多博客我发现一个共同的优点,写的让我看不懂,这就比较厉害了。终于,被我发现了一篇特别接地气的博文,此处为链接:http://www.cnblogs.com/staginner/archive/2012/10/29/2745135.html,然后接下来,就是我的叙述和理解。
因为让求的1-n区间里任两个数的最大公因数之和,所以假设gcd(n,m)=z,在这里,因为n和m的范围都是超级大,所以,不能枚举n,m,但是可以枚举m,z,或者n,z。
具体思路是:假设gcd(x,y)=1,那么当执行到x,y的时候,最后的和都要加1,那么相应的,执行到2x,2y时,最后的和都要加2,以此类推,执行到kx,ky的时候最后的和都要加k,那么这些一切的根源都归咎于gcd(x,y)=1,所以才有了上面那一句话,枚举n,z(n,m选其一,无所谓的),这里的z就是上面的1,2,。。k。枚举z的问题解决了,那么轮到n了,枚举n,假设一个值为num,那么num代表与n的最大公因数是z(1,2,3,,,,k)的个数,这里的z有好多值,但是任何的z(大于1)都可以有最根本的gcd(x,y)推出,所以算出只需要算出z=1时num的值就可以了,这个时候,就会想到欧拉函数值(小于n的数里与n互质的个数)。然后,这道题算是结束了。
【代码】
#include<map>#include<stack>#include<queue>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<iostream>#include<string>#define mem(a,b) memset(a,b,sizeof(a))#define MAXN 4000010using namespace std;const int INF=1e9;typedef long long LL;const int maxn=4e6+10;LL euler[maxn];LL a[maxn];int main(){ LL n; mem(euler,0); euler[1]=1; for(int i=2; i<=maxn; i++) { if(!euler[i])//筛法求欧拉函数值 { euler[i]=i-1; for(int j=2*i; j<=maxn; j+=i) { if(!euler[j]) euler[j]=j; euler[j]=euler[j]/i*(i-1); } } for(int j=1; i*j<=maxn; j++)//根据gcd(x,y)推出z不等于1的num值。 a[i*j]+=euler[i]*j; } for(int i=1; i<=maxn; i++)//累加。成前缀合 a[i]+=a[i-1]; while(~scanf("%lld",&n)&&n) printf("%lld\n",a[n]);}
- gcd
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- GCD
- gcd
- GCD
- GCD
- GCD
- GCD
- GCD
- html 横竖屏meta标签设置
- UIView 解析
- 关于反射与注解的实验例子
- Linux下,重新启动tomcat
- Apache服务器中的.htaccess文件的配置
- GCD
- Linux的vi问题
- 一、初始Hadoop之一Hadoop三大组件
- JAVA随笔——关于构造函数与this关键字和static关键字
- Unity性能优化(1)-官方教程The Profiler window翻译
- Android 渲染过程分析
- json的介绍
- Remote System Explorer Operation总是运行后台服务,卡死eclipse解决办法
- 医院HIS系统简介