HDU4611 Balls Rearrangement

    题意描述:有1-n编号的物品,放在0到a-1的盒子中,其中第i个物品放在 i%a 编号的盒子中,而现在要搬动物品,把这些物品放在0到b-1的盒子中,其中i物品放在i%b盒子中,每件物品移动的量为abs(ida-idb) ida,idb分别代表物品i在a,b盒子的编号,求总的移动量。

    易知循环节是LCM(a,b),但是这个循环节太大了,如果暴力更新必须超时,考虑到成段改变,因为每一段的长度len与一个步长mi的乘积就是这段物品移动的总量,注意可能出现填充不满的情况。

    还有因为没有MOD所以用int64,abs超恶心,在同时加入iostream和cstdio头文件时候会有二义性,而自己又定义一个果断CE。

#include<cstdio>
using namespace std;

#define ll __int64

ll a,b;
ll abs(ll k){
    return k>0?k:-k;
}
ll gcd(ll a,ll b){
    if(!b) return a;
    return gcd(b,a%b);
}
ll count(ll n){
    ll t,i,ret,mi;
    i=0;
    ret=0;
    while(i<n){
        t=((a-i%a)>(b-i%b))?(b-i%b):(a-i%a);
        if(i+t>n) t=n-i;
        ret+=abs(i%a-i%b)*t;
        i+=t;
    }
    return ret;
}
int main(){
    ll t,i,j,n,lcm;
    scanf("%I64d",&t);
    while(t--){
        scanf("%I64d %I64d %I64d",&n,&a,&b);
        lcm=a/gcd(a,b)*b;
        ll ret=0;
        if(lcm>n) ret=count(n);
        else ret=n/lcm*count(lcm)+count(n%lcm);
        printf("%I64d\n",ret);
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值