码迷,mamicode.com
首页 > 其他好文 > 详细

uva 10726 - Coco Monkey(数论)

时间:2014-07-22 23:02:55      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   os   io   2014   

题目链接:uva 10726 - Coco Monkey


题目大意:n个人,m只猴子,l和r,表示上下限。找出l~r之间有几个数满足题目要求。

s即为由满足要求的数,在题目中表示有s个椰子,n个人说好第二天将椰子平分,但是午夜的时候,一个人偷偷爬起来,将椰子分成n份,并且剩了m个,就将m个拿给了猴子,并且自己藏起来一份;紧接着第2个人,第3个人都按照相同的方法一直到最后一个人;然后第二天,剩下的椰子刚好平分给这n个人,这回没有猴子的了。


解题思路:这题主要是找到满足的s的个数,a数组表示说第i个人时的椰子个数a[i]=s* a[i+1]/(s-1) + m.

这种形式刚好可以转化成等比公式,假设bi = ai + k,

那么a[i] + k = (s/(s-1)) * (a[i+1] + k), 得k = m*(s-1);

这样就可以枚举最后一项个值,然后通过式子求出s,判断s是否在区间[l,r]上即可。


 

#include <cstdio>
#include <cstring>
#include <cmath>

typedef long long ll;
ll s, m, l, r;

int solve () {
	if (log2(s-1) * s > 32)
		return 0;

	ll t = s * (s - 1);
	ll d = m * (s - 1);
	ll p = pow(s, s);
	ll q = pow(s-1, s);

	int ans = 0;

	for (ll i = t; i <= 1e8; i += t) {
		ll u = (i + d) * p;

		if (u % q)
			continue;

	   	u = u / q - d;

		if (u > r) 
			break;

		if (u >= l)
			ans++;
	}
	return ans;
}

int main () {
	int cas;
	scanf("%d", &cas);
	for (int i = 1; i <= cas; i++) {
		scanf("%lld%lld%lld%lld", &s, &m, &l, &r);
		printf("Case %d: %d\n", i, solve());
	}
	return 0;
}

uva 10726 - Coco Monkey(数论),码迷,mamicode.com

uva 10726 - Coco Monkey(数论)

标签:style   blog   http   os   io   2014   

原文地址:http://blog.csdn.net/keshuai19940722/article/details/24727205

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!