HPU 1046: QAQ的数学问题 【贝祖定理】
2016-12-01 14:25
204 查看
1046: QAQ的数学问题 [数学]
时间限制: 1 Sec 内存限制: 128 MB提交: 61 解决: 11
[提交][状态][讨论版]
题目描述
QAQ很喜欢数学,尤其对LCMLCM(最小公倍数)很感兴趣。对于数对(6,10)(6,10),可以得出LCM(6,10)=30LCM(6,10)=30。为了让LCMLCM的值最小化,他尝试把66和1010全部加上22,这样得到LCM(8,12)=24<30LCM(8,12)=24<30。
经过无数次的尝试,QAQ发现总是可以通过上面相加的方式(必须加的是非负整数)让LCMLCM的值达到最小的,但是他忘记至少需要加多少了,所以你来请帮帮他吧。
输入
第一行输入一个整数TT,代表有TT组测试数据。每组数据输入两个整数A,BA,B,分别代表上面提到信息。
注:1<=T<=2000,1<=A,B<=20000000001<=T<=2000,1<=A,B<=2000000000。
输出
对每组数据,输出一个结果,代表QAQ至少需要加的数。
样例输入
3 6 10 4 10 3 10
样例输出
2 2 4
来源
CZY题解:
因为A和B的差始终是不变的,那么考虑差对结果的影响。
发现不管怎么变,GCD(A,B)就是abs(A−B)的一个因子。
我们预处理因子,然后枚举因子维护最优解即可。
时间复杂度O(T∗log(abs(A−B)))。
AC代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
int f[10111];
LL GCD(LL a,LL b) {
return !b?a:GCD(b,a%b);
}
LL LCM(LL a,LL b) {
return a/GCD(a,b)*b;
}
int main() {
LL T; scanf("%lld",&T);
while(T--) {
LL a,b; scanf("%lld%lld",&a,&b);
if(a<b) swap(a,b);
LL m=a-b,i,cnt=0;
for( i=1;i*i<m;++i) {
if(m%i==0) {
f[cnt++]=i; f[cnt++]=m/i;
}
}
if(m%i==0) f[cnt++]=i;
LL ans=LCM(a,b),x=0;
for(i=0;i<cnt;++i) {
LL j=f[i]-b%f[i];//求b对于f[i]的逆 不要用while去找 会T
LL tem=(a+j)/f[i]*(b+j);
if(tem<ans) {
ans=tem; x=j;
}
}
printf("%lld\n",x);
}
return 0;
}
相关文章推荐
- 【HPU 1046 QAQ的数学问题】+ 思维
- HPU 1010: QAQ的序列价值【状压&组合数学】
- hpuoj-1010-QAQ的序列价值【状压】【数学组合】
- 【HPU 1048 QAQ的纸币问题(二)】+ 思维
- 【HPU 1047 QAQ的纸币问题(一)】+ 思维
- 数学+精度 hpu 1207: 杨八方的问题
- 【HPU 1410 1410: QAQ & 火星情报局 】 数学 & 规律 & 哥特巴赫的猜想
- 【hpu oj 1010 QAQ的序列价值 [数学、状态压缩]】
- hpu 1214: 毛毛的数学问题(1)
- HPU 1410 QAQ & 火星情报局 (数学)
- 【HPU】[1731]QAQ的问题
- HPU 1410: QAQ & 火星情报局 ( 数学
- 数学排列好难--- QAQ的问题
- hpu 1215: 毛毛的数学问题
- HPU1009 QAQ的区间价值【数学找规律】
- 关于数学问题的程序解决,找出推导式及西大OJ_14解答
- [裴礼文数学分析中的典型问题与方法习题参考解答]4.5.6
- 趣味问题之趣味数学
- 《挑战程序设计竞赛》2.6.1 数学问题-辗转相除法 AOJ0005 POJ2429 1930(1)
- poj 1844 数学问题