GCD
2016-06-22 16:15
411 查看
题目描述
Given an integer N and M, you have to calculateHere GCD(N,K) means the greatest common divisor of integer N and integer K
.
输入
The first line contains a single integer T(1≤T≤10), indicating the number of test cases.Each test case contains two integers N and M (1≤N,M≤109).
输出
Output the required answer modulo 109+7 for each test case, one per line.样例输入
24 2
2 5
样例输出
2430
#include <iostream> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define M 1000000007 #define LL long long int a[1024], b[1024]; int num, num1; void gcd(int n) { num = 0; for (int i = 1; i <= sqrt(n); ++i) { if ((n % i) == 0) { a[num++] = i; a[num++] = n / i; if (n / i == i) num--; } } sort(a,a + num); num1 = n; for (int i = num-1; i >= 0; --i) { b[i] = n/a[i]; for (int j = num-1; j > i ; --j) { if(a[j] % a[i] == 0) b[i] -= b[j]; } num1 -= b[i]; } } LL test(LL m, int gcd) { LL sum = 1; while(gcd){ if(gcd % 2 == 1) sum = (sum * m) % M; m = (m * m) % M; gcd >>= 1; } sum = sum % M; return sum; } int main() { int t, n; LL s, m; cin >> t; while (t--) { cin >> n >> m; if (n == 1){ printf("%lld\n",m); continue; } s = 0; num1 = 1; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); gcd(n); for (int i = 0; i < num; ++i) { //cout << a[i] << ", " << b[i] << endl; s = (s + b[i] * test(m, a[i])) % M; } //cout << num1 << endl; s = (s + m * (num1)) % M; s = s % M; printf("%lld\n",s); } return 0; }
这道题逻辑是很简单的,但是按着最普通的方法做,你都不知道到超时多久了,所以得用特殊的方法。这里有幂,我们就用快速幂的方法。还有大数求最大公约数,我之前用的是辗转相除法,一直到10000000就不行了,时间超过了1s。后来用了遍历求约数的方法,结果到1000000000大概要3s,真的是醉了。最后在遍历的基础上,做了些剪枝,然后速度快得飞起~。 其实辗转相除法是算比较快的了,只不过这里的题目要有好多次求最大公约数,所以这里不适合。先求约数的方法显然更适合这种方法。
在做题目的时候翻到一个不错的讲GDC的博客
http://www.cnblogs.com/zhangshu/archive/2011/07/20/2111276.html
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C++联合体转换成C#结构的实现方法