hdu 2588
来源:互联网 发布:软件开发工程量清单 编辑:程序博客网 时间:2024/04/28 04:09
http://acm.hdu.edu.cn/showproblem.php?pid=2588
又一道欧拉函数题,题目要求小于等于n且与n的最大公约数大于等于m的所有数的个数
欧拉函数只能求出小于n且与n互质的所有数的个数,但是无法求出最大公约数是否大于m
但是 我们可以这样想 设a为大于等于m的n的一个约数,那么euler(n/a)表示的就是所有小于a与a互质的数的个数,设任一个数为x,那么这些数再乘以a就有gcd(n,x*a) = a;
所以我们可以想到答案为所有n大于等于m的约数ai的euler(n/ai)之和
但是还有一个问题 这些数是否会重复呢?答案是否定的
设a、b为两个不同的大于等于m的n的约数
假设存在重复 那么就有 a*x = b*y (x是小于等于n/a且与n/a互质的数,y是n/b的。。)
变形 得到 x*n/b = y*n/a 由于x和n/a互质 所以 x是y的约数(因为两边分解质因数的时候n/a不能分出x的约数 只能是y来分)
不妨设 y = kx(k>1) 则 n/b = k(n/a)
由于y和n/b互质 则kx和n/b互质 但是n/b有个k作为约数 所以他们有公约数k 这显然推出k = 1 于是产生a==b矛盾!
所以不会产生重复
最后注意一下 m=1的时候答案就是n 直接加结果貌似不对
贴段代码
#include <string.h>#include <iostream>#include <stdio.h>#include <math.h>using namespace std;int euler(int n){ int temp = n;int sq_n = sqrt(n+0.5);int ans = n;for(int i = 2;i<=sq_n;i++){if(n%i==0){ans = ans/i*(i-1);while(n%i==0) n/=i;}}if(n>1) ans = ans/n*(n-1);return ans;}int main(void){//freopen("","r",stdin);int t;scanf("%d",&t);while(t--){int n,m;scanf("%d %d",&n,&m);if(m==1){ printf("%d\n",n); continue;}int ans = 0;int sq_n = sqrt(n+0.5);for(int i = 2;i<=sq_n;i++){if(n%i==0){ if(i>=m) ans+=euler(n/i);if(n/i>=m) ans+=euler(i);}}if(n!=1&&sq_n*sq_n==n&&sq_n>=m) ans-=euler(sq_n);printf("%d\n",ans+1);}}
- hdu 2588
- hdu 2588
- hdu 2588
- hdu 2588
- hdu 2588 欧拉函数 &&hdu 2504
- HDU 2588 GCD
- hdu 2588 GCD
- hdu 2588 GCD
- hdu-2588 GCD
- HDU 2588题解
- hdu 2588 GCD
- hdu 2588 GCD
- HDU 2588 GCD
- HDU 2588 GCD
- HDU 2588 GCD
- HDU 2588 GCD
- HDU-2588-GCD
- 欧拉函数 HDU 1286 HDU 2588 HDU 2824 HDU 4983
- Android 常用 mimeType 表
- 开发中遇到的DLL问题思考及解决方法 2008-06-27 20:49:18
- 安卓中的hander
- Oracle数据库表连接方式及常见用法
- struts2:关于EL能够获得action的属性
- hdu 2588
- android中textview的左右对齐
- 不使用额外空间字符串去重
- 三种糟糕的程序员
- C语言声明数组变量时,在什么情况下,可不指定数组大小
- Struts2教程六——Form Validation
- SWOT分析模型
- 碰到:Could not execute: Access denied(Win32 error 5),
- 两种方法查看MFC源代码