题目链接
题意
有很多人进行一场比赛,比赛是1v1的形式,不会平局,只有胜场和输场数完全相同的选手才能进行比赛,当胜场数到达
n
n
n或者败场数到达
m
m
m时,选手将不再参与比赛.比赛完全结束后,主办方将给所有比赛全败的选手颁发一个英勇不屈奖章,问最少要准备多少枚奖章.
题解
观察样例发现所有的答案肯定是
2
2
2的某个幂,且
n
,
m
n,m
n,m可以交换.再仔细思考,我们意识到当参赛的总人数是
2
2
2的一个幂时,存在某种胜负场数的人数是奇数,此时参赛的总人数最少,准备的奖章数量也最少.显然这和杨辉三角有关,因此这既是一个二进制数论题也是一个组合数数论题. 再仔细分析,当一名选手以胜场数达到
n
n
n结束比赛时,他的负场数为
i
i
i,则这样的人数为
C
p
+
i
?
1
i
C^{i}_{p+i-1}
Cp+i?1i?,满足这个数为奇数的条件
p
>
n
+
i
?
_
b
p
(
n
)
?
_
b
p
(
i
)
+
_
b
p
(
n
+
i
)
p>n+i-\_bp(n)-\_bp(i)+\_bp(n+i)
p>n+i?_bp(n)?_bp(i)+_bp(n+i),其中
_
b
p
\_bp
_bp为__builtin_popcount 的简称.由于
n
n
n为
1
0
6
10^6
106,所以
i
<
n
?
20
i<n-20
i<n?20时,上式便不能出现最大值,故只要暴力枚举
20
20
20个
i
i
i便可得到最优的结果,最后只要用简单的快速幂把答案算出来就好了.
const int yuzu=1e6,mod=1e9+7;
int main() {
for (int t=read();t--;) {
ll n,m,zw=0,i;
#define _bp __builtin_popcount
read(n),read(m),--n,--m;
auto kasumi=[&](ll a,ll b=mod-2) {
ll zw=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) zw=zw*a%mod;
return zw;
};
for (i=max(0ll,m-20);i<=m;++i) zw=max(zw,n+i+1-_bp(n)-_bp(i)+_bp(n+i));
printf("%lld\n",kasumi(2,zw-m-1));
}
}
谢谢大家.
|