题意
有
n
n
n个球要放到
m
m
m个箱子里,有以下两条规则:
1、若把标号为
i
i
i的球放进了第
j
j
j个盒子,那么标号为
2
∗
i
2*i
2∗i的球一定要在第
j
+
1
j+1
j+1个盒子里面
(
(
(若
j
<
m
)
j<m)
j<m)
2、若把标号为
i
i
i的球放进了第
j
j
j个盒子,并且
k
∗
2
=
i
k*2=i
k∗2=i,那么标号为
k
k
k的球一定要在第
j
−
1
j-1
j−1个盒子里面
(
(
(若
j
>
1
)
j>1)
j>1)
求第一个箱子里最多可以放多少球。
思路
因为
2
2
2,所以第一个箱子里只能放奇数编号的球。
如果第一个箱子里放
a
a
a,那么
a
∗
2
m
−
1
≤
n
a*2^{m-1}\leq n
a∗2m−1≤n
那么我们就知道
2
m
2^m
2m里可以放了,然后有
a
∗
2
x
(
x
≡
0
(
m
o
d
m
)
,
a
≡
1
(
m
o
d
2
)
,
a
∗
2
x
+
m
−
1
<
=
n
)
a∗2^x(x≡0(mod\ m),a≡1(mod\ 2),a∗2^{x+m−1}<=n)
a∗2x(x≡0(mod m),a≡1(mod 2),a∗2x+m−1<=n)
所以我们每次让
n
/
2
m
−
1
n/2^{m-1}
n/2m−1,统计一遍奇数,然后每次让
n
/
2
m
n/2^m
n/2m,统计奇数。
因为
n
n
n比较大,所以我们需要用高精度。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
const long long P = 1e11;
const int MAXN = 1000;
int t, m, l, al;
long long a[MAXN + 1], ans[MAXN + 1];
char s[10001];
void init() {
memset(s, 0, sizeof(s));
memset(ans, 0, sizeof(ans));
scanf("%s", s + 1);
scanf("%d", &m);
l = strlen(s + 1);
int g = 0;
long long k = 1;
for (int i = l; i >= 1; i--) {
a[g] += (s[i] - 48) * k;
k *= 10;
if (k == P) k = 1, g++;
}
l = MAXN;
al = 0;
}
void div(long long d) {
long long g = 0;
for (int i = l; i >= 0; i--) {
a[i] += g * P;
g = a[i] % d;
a[i] /= d;
}
while (!a[l] && l)
l--;
}
void countAns() {
long long g = 0;
ans[0] += a[0] % 2;
for (int i = l; i >= 0; i--) {
ans[i] += (a[i] + g * P) / 2;
g = a[i] % 2;
}
int t = std::max(l - 1, al);
if (ans[t + 1]) t++;
for (int i = 0; i <= t; i++)
if (ans[i] >= P) {
ans[i] -= P;
ans[i + 1]++;
}
if (ans[t + 1]) al = t + 1;
else al = t;
}
void print() {
printf("%lld", ans[al]);
while (al--) {
if (ans[al] < 1e10) printf("0");
if (ans[al] < 1e9) printf("0");
if (ans[al] < 1e8) printf("0");
if (ans[al] < 1e7) printf("0");
if (ans[al] < 1e6) printf("0");
if (ans[al] < 1e5) printf("0");
if (ans[al] < 1e4) printf("0");
if (ans[al] < 1e3) printf("0");
if (ans[al] < 1e2) printf("0");
printf("%lld", ans[al]);
}
printf("\n");
}
int main() {
scanf("%d", &t);
for (; t; t--) {
init();
div(1 << m - 1);
countAns();
while (a[0]) {
div(1 << m);
countAns();
}
print();
}
}