hdu4710
Balls Rearrangement
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 344 Accepted Submission(s): 165
Some day Bob buys B new boxes, and he wants to rearrange the balls from the old boxes to the new boxes. The new boxes are numbered from 0 to B-1. After the rearrangement, the ball numbered x should be in the box number b if x = b mod B.
This work may be very boring, so he wants to know the cost before the rearrangement. If he moves a ball from the old box numbered a to the new box numbered b, the cost he considered would be |a-b|. The total cost is the sum of the cost to move every ball, and it is what Bob is interested in now.
Then T test case followed. The only line of each test case are three integers N, A and B.(1<=N<=1000000000, 1<=A,B<=100000).
1000000000 1 1
8 2 4
11 5 3
8
16
/*分析:对于i%a - i%b,每次加上从i开始和这个值(i%a - i%b)相等的一段,
这样i就不是每次+1,而是每次加上一段,如果碰到n大于a,b的最小公倍数,
则只需要计算a,b最小公倍数长度的总和,然后sum*=n/per + p;//p表示前i个数,p=n%per; 本题反思:刚开始自己就是这样想,但是想到a,b的最小公倍数可能很大,而且n也很大,
如果刚好碰到n<per但是n很大;//per表示a,b最小公倍数,或者碰到n>per但是per很大
即使一段段的算也可能超时,所以一直不敢下手,一直在找寻更简单的推论。。结果一直没找到
下次碰到这种情况应该先试试,不能找不出别的更简单的方法就连自己想到的方法都不试试 现在认真分析发现时间复杂度好像是:O((a/b * min(per,n)/a));//假设a>=b
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<cmath>
#include<math.h>
#include<iomanip>
#define INF 99999999
using namespace std; const int MAX=10;
__int64 p; __int64 Gcd(__int64 a,__int64 b){
if(b == 0)return a;
return Gcd(b,a%b);
} __int64 calculate(__int64 n,__int64 a,__int64 b,__int64 num){
p=0;
__int64 la=a,lb=b,sum=0,l;
for(__int64 i=0;i<n;){
l=min(la,min(lb,n-i));
if(i+l>num && i<num)p=sum+abs((int)(i%a - i%b))*(num-i);
sum+=abs((int)(i%a - i%b))*l;
i+=l;
la=(la-l+a-1)%a+1;
lb=(lb-l+b-1)%b+1;
}
return sum;
} int main(){
__int64 n,a,b,t;
scanf("%I64d",&t);
while(t--){
scanf("%I64d%I64d%I64d",&n,&a,&b);
__int64 gcd=Gcd(a,b),per=a*b/gcd,k=min(per,n);//求出最小公倍数
__int64 sum=calculate(k,a,b,n%k);
if(n>per)sum=(n/per)*sum+p;//p表示前n%k个i%a-i%b的和
printf("%I64d\n",sum);
}
return 0;
}
hdu4710的更多相关文章
- [hdu4710 Balls Rearrangement]分段统计
题意:求∑|i%a-i%b|,0≤i<n 思路:复杂度分析比较重要,不细想还真不知道这样一段段跳还真的挺快的=.= 令p=lcm(a,b),那么p就是|i%a-i%b|的循环节.考虑计算n的答案 ...
- hdu4710 Balls Rearrangement(数学公式+取模)
Balls Rearrangement Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
随机推荐
- ASP.net体系
- CodeForce 569A
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description Litt ...
- mysql root密码重置
1.修改my.cnf #位置一般是 /etc/my.cnf 2.重启mysql服务 service mysqld restart 3.进入mysql mysql -uroot -p 然后直接回车 4. ...
- Python网络编程——通过指定的端口和协议找到服务名
1.通过指定的端口和协议找到对应的服务名,采用socket中getservbyprot()函数实现. import socket def find_service_name(): protocolna ...
- [LeetCode]题解(python):016-3Sum Closest
题目来源: https://leetcode.com/problems/3sum-closest/ 题意分析: 这道题目输入一个数组nums和一个数target,找出数组中三个数,使得他们的和最接近t ...
- [LeetCode]题解(python):009-Palindrome Number
题目来源: https://leetcode.com/problems/palindrome-number/ 题意分析: 这题是要判断一个int是否一个回文数,要求不能申请额外的空间. 题目思路: 这 ...
- tf–idf算法解释及其python代码实现(上)
tf–idf算法解释 tf–idf, 是term frequency–inverse document frequency的缩写,它通常用来衡量一个词对在一个语料库中对它所在的文档有多重要,常用在信息 ...
- 转: RequireJS Optimizer 的使用和配置方法
RequireJS Optimizer 是 RequireJS 自带的前端优化工具,可以对 RequireJS 项目中的JavaScript和CSS 代码使用 UglifyJS 或者 Closure ...
- FLASH ROM与EEPROM的区别
EEPROM,虽然也叫“非易失性数据存储器”,但它不能直接参与ALU运算,只是用于掉电不丢失的数据存储. EEPROM和片内RAM 类似,也属于数据存储器,它的特点是数据掉电可保持,而程序存储器一般指 ...
- 给EditText中的图片加监听
package com.example.helloword; import android.app.Activity; import android.content.Context; import a ...