题意
有n个学生打羽毛球,其中有a个人没拍没球,b个人只有拍,c个人只有球,d个人有拍有球。
现在要求选出几个人组织一场比赛,一共有
2n
2
n
种情况,组织成功的条件是至少有2个拍1个球。求有多少种情况无法组织成功。
思路
一开始想组织成功的,但是发现情况太多太复杂,只要有2拍1球就可以,那么可能会有2排1球,2排2球,3排1球,3排2球……不好列举。
反过来想无法组织成功的情况并不多:0排0球,0拍n球,1排n球,n排0球。
可以列出组合公式:
ans=∑i=0aCia∗[1+∑i=1bCib+∑i=1cCic∗(b+d+1)+d]
a
n
s
=
∑
i
=
0
a
C
a
i
∗
[
1
+
∑
i
=
1
b
C
b
i
+
∑
i
=
1
c
C
c
i
∗
(
b
+
d
+
1
)
+
d
]
其中把组合数求和改成2的…次幂
ans=2a∗[1+(2b−1)+(2c−1)∗(b+d+1)+d]
a
n
s
=
2
a
∗
[
1
+
(
2
b
−
1
)
+
(
2
c
−
1
)
∗
(
b
+
d
+
1
)
+
d
]
再利用快速幂取模计算即可
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mod = 998244353;
ll quickmi(ll a, ll b){
int ans = 1;
a = a % mod;
while(b){
if(b&1)ans = (ans * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return ans%mod;
}
int main()
{
int T;
ll a, b, c, d;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
printf("%lld\n",quickmi(2,a)%mod*(1+(quickmi(2,b)-1)%mod+((quickmi(2,c)-1)%mod*(b+d+1)%mod)%mod+d)%mod);
}
return 0;
}