Description
有nn个人打球,分成四种,个人没有球拍没有球,bb个人只有球拍没有球,个人只有球没有球拍,dd个人既有球拍也有球,问从这个人中选出若干使得没有两只球拍一个球的方案数
Input
第一行一整数TT表示用例组数,每组用例输入四个整数
(1≤T≤103,0≤a,b,c,d≤107,a+b+c+d≥1)(1≤T≤103,0≤a,b,c,d≤107,a+b+c+d≥1)
Output
输出方案数,结果模998244353998244353
Sample Input
3
1 1 1 1
2 2 2 2
3 4 5 6
Sample Output
12
84
2904
Solution
考虑不合法方案,即凑够两个球拍一个球,分三种情况:
1.从dd个人中至少选两个,那么前个人随便选,方案数(2d−d−1)⋅2a+b+c(2d−d−1)⋅2a+b+c
2.从dd个人中选一个,那么要从个人中至少选一个,其他人随便选,方案数d⋅(2b−1)⋅2a+cd⋅(2b−1)⋅2a+c
3.dd个人不选,个人中至少选两个,cc个人中至少选一个,方案数
Code
#include<cstdio>
using namespace std;
typedef long long ll;
#define mod 998244353
int T,a,b,c,d;
int mul(int x,int y)
{
ll z=1ll*x*y;
return z-z/mod*mod;
}
int add(int x,int y)
{
x+=y;
if(x>=mod)x-=mod;
return x;
}
int Pow(int x,int y)
{
int ans=1;
while(y)
{
if(y&1)ans=mul(ans,x);
x=mul(x,x);
y>>=1;
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
int ans=Pow(2,a+b+c+d);
int t=mul(Pow(2,a),mul(add(Pow(2,b),mod-b-1),add(Pow(2,c),mod-1)));
ans=add(ans,mod-t);
t=mul(d,mul(mul(add(Pow(2,b),mod-1),Pow(2,a)),Pow(2,c)));
ans=add(ans,mod-t);
t=mul(add(Pow(2,d),mod-d-1),Pow(2,a+b+c));
ans=add(ans,mod-t);
printf("%d\n",ans);
}
return 0;
}