欧拉函数和最大公约数的组合应用
2014-04-28 16:28
288 查看
这种问题一般都是给出限制条件:给你一个数N(N一般很大),使得在1~N之间能够找到X使得X满足gcd(
X , N ) >= M,然后求解相关的问题。
分析:这是一种统计类型的问题。比较容易想到的解法就是枚举gcd(X,N)的值,对于枚举到的某个gcd(X,N) 的值 d,如果令 N = p * d,X = q * d,那么如果 gcd(X,N) = d,一定有 p,q 互质,又有 X <= N,则 q <= p,而这样的 q 的个数正好对应p的欧拉函数,即满足gcd(X,N) = d 的X的个数为N/d 的欧拉函数值。
应用1:求满足条件的X的个数。http://acm.hdu.edu.cn/showproblem.php?pid=2588
GCD
Time Limit: 2000/1000 MS (Java/Others) Memory Limit:32768/32768 K (Java/Others)
Problem Description
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to a and b,For example,(1,2)=1,(12,18)=6.
(a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.
Input
The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (2<=N<=1000000000, 1<=M<=N), representing a test case.
Output
For each test case,output the answer on a single line.
Sample Input
3 1 1 10 2 10000 72
Sample Output
1 6 260
分析:对于这个问题,因为只需要求出满足题意的X的个数,所以可以枚举最大公约数d,而满足gcd(X,N) = d 的X的个数就是N/d的欧拉函数,把这些d对应的N/d的欧拉函数值求和即可。
#include<stdio.h> #include<math.h> int euler(int n) { int m = (int)sqrt(n+0.5); int ans = n; for(int i = 2; i <= m; 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() { int t, n, m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int ans = 0; for(int i = 1; i * i <= n; i++) //枚举最大公因数 { if(n % i == 0) { if(i >= m) ans += euler(n/i); if(i * i != n && n / i >= m) ans += euler(i); } } printf("%d\n", ans); } return 0; }
应用2:求满足条件的gcd(X,N)的和。http://acm.nyist.net/JudgeOnline/problem.php?pid=998
Sum
时间限制:1000 ms | 内存限制:65535 KB难度:3
描述
给你一个数N,使得在1~N之间能够找到x使得x满足gcd( x , N ) >= M,
求解gcd(x,N)的和
输入多组测试数据
每行输出两个数N,M(N,M不超int)
输出输出sum
样例输入
5 3
样例输出
5
分析:这个题要求gcd(X,N)的和,因为上一题已经求出了满足题意的个数,所以只需要在上一题的基础上乘以最大公约数就是最终答案。
#include<stdio.h> #include<math.h> typedef long long LL; LL euler(LL n) //n的欧拉函数值 { LL ans = n; for(LL i = 2; i * i <= 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() { LL n, m; while(~scanf("%lld%lld",&n,&m)) { LL ans = 0; LL tmp = (LL)sqrt(n+0.5); for(LL i = 1; i <= tmp; i++) //枚举最大公因数 { if(n % i == 0) { if(i >= m) ans += euler(n/i) * i; if(i * i != n && n / i >= m) ans += euler(i) * (n / i); } } printf("%lld\n", ans); } return 0; }
应用3:求所有满足条件的X的和。http://acm.nyist.net/JudgeOnline/problem.php?pid=1007
GCD
时间限制:1000 ms | 内存限制:65535 KB难度:3
描述The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the largest divisor common to
a and b,For example,(1,2)=1,(12,18)=6.
(a,b) can be easily found by the Euclidean algorithm. Now Carp is considering a little more difficult problem:
Given integers N and M,please answer sum of X satisfies 1<=X<=N and (X,N)>=M.
输入The first line of input is an integer T(T<=100) representing the number of test cases. The following T lines each contains two numbers N and M (1<=N<=10^9, 1<=M<=10^9), representing a
test case.
输出Output the answer mod 1000000007
样例输入
3 1 1 10 2 10000 72
样例输出
1 35 1305000
分析:这个题和前两个题基本上一样,只需要在枚举最大公约数d时,求出gcd(X,N) = d 的所有X的和即可。根据上面可以得出:满足条件的X个数有euler(N/d)个,所以只需要求出不超过N/d且与N/d互素的那些数的和,然后乘以d就是最大公约数为d时对应的部分结果。而不超过N/d且与N/d互素的那些数的和
= N/d * euler(N/d) / 2,注意当N/d = 1时,结果是1而不是0。了解了这些,就可以解决这个题了。
除了1、2以外,所有数的欧拉函数都是偶数。
如果k <= n 并且 (k,n) = 1, 那么(n-k, n) = 1;
#include<stdio.h> #define mod 1000000007 typedef long long LL; LL euler(LL n) //n的欧拉函数值 { LL ans = n; for(LL i = 2; i * i <= 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; } LL euler_sum(LL n) //求和n互素的数的和 { if(n == 1) return 1; return n * euler(n) / 2; } int main() { int t; LL n, m; scanf("%d",&t); while(t--) { scanf("%lld%lld",&n,&m); LL ans = 0; for(LL i = 1; i * i <= n; i++) //枚举最大公因数 { if(n % i == 0) { if(i >= m) ans = (ans + euler_sum(n/i) * i) % mod; if(i * i != n && n / i >= m) ans = (ans + euler_sum(i) * (n / i)) % mod; } } printf("%lld\n", ans); } return 0; }
相关文章推荐
- BZOJ 2818: Gcd区间内最大公约数 为素数的对数(欧拉函数的应用)
- 欧拉函数和最大公约数的应用
- HDU 2582-f(n)(求n个组合数最大公约数的和)
- 利用欧拉函数解决最大公约数相关问题
- 【51nod】1040 最大公约数之和 欧拉函数
- 约数,公约数及最大公约数在图片特效中的应用
- [欧拉函数]51nod 1040 最大公约数之和 题解
- 51NOD 1040 最大公约数之和(分析 + 欧拉函数)
- 【欧拉函数】51Nod1040[最大公约数之和]题解
- 51nod 1040最大公约数和(欧拉函数)
- 51nod 1040 最大公约数之和(欧拉函数)
- 51nod-1040-1040 最大公约数之和(欧拉函数)
- 求两个整数的最大公约数及其应用
- [算法设计与分析]3.4.2最大公约数的应用(循环移动数组元素)
- 【51nod1040】【最大公约数之和】【欧拉函数】
- (《数论及应用1.3》NEFU 116 两仪剑法(最小公倍数&&最大公约数))
- C#--第2周实验--任务五--编写一个控制台应用--求两个整数的最小公倍数与最大公约数
- NYOJ 题目569最大公约数之和(欧拉函数,数学)
- HDU 1722 Cake 最大公约数应用
- 将两个正整数的最大公约数表示成两个数的线性组合, data1 * n + data2 *m = gcd(data1, data2)