Educational Codeforces Round 116 (Rated for Div. 2) B. Update Files

Educational Codeforces Round 116 (Rated for Div. 2) 的其他题解点我

B. Update Files

题目链接


题目大意:
有n个人,最初只有1知道消息,每次每个人可以传递一次消息给另一人,每次传递最多只有k个人可以进行传递,问最小需要多少次才能使所有人都知道消息

思路:
如果不考虑k
第一次有1个人可以传
第二次有2个人可以传
第三次有4个人可以传
第n次就有2 ^ n个人可以传

然后我们枚举前64次,如果次数超过k则弹出,或者传递完也弹出

因为有k的限制,我们后面只能传k个人
就需要 ⌈ ( n − p r e [ i ] ) / k ⌉ \lceil(n - pre[i] )/k\rceil (npre[i])/k
就是减去前面的部分, 后面除k向上取整就好了

AC代码:

#include <bits/stdc++.h>
#define PII pair<int,int>
#define ll long long

using namespace std;

const double eps = 1e-8;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
const int INF = 1<<30;
inline void swap(int &x, int &y){x^=y^=x^=y;}
inline int gcd(int a,int b) {return !b ? a : gcd(b,a%b);}

ll pre[100];
int main() {
	pre[0] = 1;
	for (int i = 1; i < 64; ++i) 
		pre[i] = pre[i - 1] << 1;
	int T;
	scanf("%d", &T);
	while (T--) {
		ll n, k;
		scanf("%lld %lld", &n, &k);
		if (k == 1) printf("%lld\n", n - 1);
		else {
			int i = 0;
			for (; i < 64; i++)
				if (pre[i] >= n || pre[i] > k)break;
			ll ans = i;
			if (pre[i] < n) 
				ans += (n - pre[i] + k - 1) / k;
			printf("%lld\n", ans);
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值