题意是要我们把已经按序号放入A类盒子的球放入B类盒子,问其中操作所需要的移动距离为多少。
因为球的数量为10^9盒子也是10^5的数量级
如果一个一个球的去计算的话很容易TLE,所以就按段求和,每一个移动距离相同的段我们进行统一计算
这样每次差不多最多计算A+B次,这样就避免了TLE的问题了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <list>
#include <map>
using namespace std;
long long gcd(long long x,long long y)
{
//cout<<x<<' '<<y<<endl;
if(x % y != 0)
{
return gcd(y,x%y);
}
return y;
}
long long lcm(long long x,long long y)
{
long long c = gcd(x,y);
//cout<<x<<' '<<y<<' '<<c<<endl;
return x * y / c;
}
long long n,a,b,ans,sum,wei,lun,aa,bb,add,ll;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d%I64d",&n,&a,&b);
long long l = lcm(a,b);
wei = n % l;
lun = n / l;
//cout<<l<<' '<<wei<<' '<<lun<<endl;
ll = ans = sum = 0;
while(ll < l)
{
add = abs(ll % a - ll % b);
int c = min(a - ll % a,b - ll % b);
if(c + ll < l)
{
sum += c * add;
ll += c;
}
else
{
sum += (l - ll) * add;
ll = l;
}
}
ll = 0;
while(ll < wei)
{
add = abs(ll % a - ll % b);
int c = min(a - ll % a,b - ll % b);
if(c + ll < wei)
{
ans += c * add;
ll += c;
}
else
{
ans += (wei - ll) * add;
ll = wei;
}
}
ans += sum * lun;
printf("%I64d\n",ans);
}
return 0;
}