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
⌈(n−pre[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;
}