3192. 【中山市选2013】球

63 篇文章 0 订阅

Description

小包有N个球和A个盒子。球标号为0到N-1,盒子编号为0到A-1。标号为x的球放在下标为x mod A的盒子里。

然后他得到了B个新盒子,编号为0到B-1。他想把所有球从旧盒子里面拿出来放到新盒子,标号为x的球放在下标为x mod B的盒子里。

对于某个球来说,如果原本放在下标为a的旧盒子,现在放在下表为b的新盒子,那么费用为|a-b|。

求出总花费。

Input

输入3个整数N,A和B,同一行。

Output

输出总花费。

Sample Input

输入1:

1000000000 1 1



输入2:

8 2 4

 

Sample Output

输出1:

0



输出2:

8

Data Constraint

对于30%的数据有1≤N≤20

对于全部数据,有1≤N≤1000000000,A,B≤100000

Solution

我们先将n变成a的倍数,剩下不足a个暴力。

我们根据循环节先找出所有%a=0的数,记s[x]为这些数中%b=x的个数,t[x]为s[x]*x,然后我们枚举%a的余数k,可以发现所有%a=k的数的数量是等于%a=0的数的数量的,并且,我们可以将这些数看作%a=0的每个数+k得来。接着,对于这些数中原先%b=x的数,它的新的余数就变成了(x+k)%b,可以将b数组看成整体向右移了k位,超过k的变成1,因此,对于k我们可以用%a=0的转移过来。具体只要分类讨论| i%a - i%b |的绝对值内数的正负性。

1.若是正的,即k>i%b,i%b取0~k-1中的数,那么我们要取的数即为(x+k)%b的范围在0~k-1中的所有x,然后这些数的个数*k-sum(i%b)就是答案。

2.若是负数,即k<i%b,i%b取k+1~b-1中的数,类似求答案。

 

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
#define ll long long
using namespace std;
int n,a,b;
ll ans,sum,s[N],t[N];
int main(){
	freopen("ball.in","r",stdin);
	freopen("ball.out","w",stdout);
	scanf("%d%d%d",&n,&a,&b);
	if(a>b) swap(a,b);
	for(int i=(n/a)*a;i<=n-1;i++) sum+=abs(i%a-i%b);
	n=(n/a)*a;
	for(int i=0;i<=n/a-1;i++){
		int r=(i*a)%b;
		if(!s[r]) s[r]++;
		else{
			int k=(n/a)/i;
			for(int j=0;j<=b-1;j++) s[j]*=k;
			for(int j=i*k+1;j<n/a;j++) s[(j*a)%b]++;
			break;
		}
	}
	t[0]=s[0];
	for(int i=1;i<=b-1;i++){
		t[i]=t[i-1]+s[i]*i;s[i]+=s[i-1];
	}
	for(int k=0;k<=a-1;k++){
		ans+=k*(s[b-1]-s[b-k-1])-(t[b-1]-t[b-k-1])+(b-k)*(s[b-1]-s[b-k-1]);
		ans+=t[b-k-1]-t[0]-k*(s[b-k-1]-s[0])+k*(s[b-k-1]-s[0]);
	}
	printf("%lld\n",ans+sum);
	return 0;
}


作者:zsjzliziyang 
QQ:1634151125 
转载及修改请注明 
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/94410772

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值