您的位置:首页 > 其它

hdu 4614(数学 + 乱搞)

2013-08-12 12:40 253 查看
题目链接

多校第二场的题目, 首先可以确定lcm(a, b)是周期,然后求出一个周期内的结果, 在一个周期内需要分段考虑,

同一个段内的差值都是相同的, 所以直接模拟每段求再累加就可以了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>

using namespace std;

typedef long long LL;

LL calc(int n, int a, int b) {
	LL ans = 0;
	int d = 0;
	int ta = a, tb = b;
	int p = 0;

	while (p < n) {
		if (tb < ta) {
			ans += (LL)d * (min(tb, n) - p);
			p = tb;
			d = labs((p % a) - (p % b));
			tb += b;	
		}
		else {
			ans += (LL)d * (min(ta, n) - p);
			p = ta;
			d = labs((p % a) - (p % b));
			ta += a;		
		}	
	}

	return ans;
}

LL gcd(LL a, LL b) {
	return b == 0 ? a : gcd(b, a % b);
}

LL lcm(LL a, LL b) {
	return a / gcd(a, b) * b;
}

int main() {
	int test, n, a, b;
	LL r;

	scanf("%d", &test);
	while (test--) {
		scanf("%d%d%d", &n, &a, &b);
		if (a == b) {
			puts("0");
			continue;
		}
		r = lcm(a, b);
		LL tmp = calc(r, a, b);
		LL res = n / r * tmp + calc(n % r, a, b);
		printf("%I64d\n", res);
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: