题目背景
(Tairitsu)给(Hikari)出了一个组合数的题
题目描述
求出(egin{aligned}sum_{i=0}^xC_{x}^i*C_{y}^{z+i}\%998244353end{aligned})
Hikari稍微想了想这不是个傻叉的杨辉三角吗,但她看到数据范围后就更懵逼了,于是她来寻求你的帮助。
输入格式
第一行一个整数(T)表示数据组数。
接下来(T)行,每行分别有三个整数(x),(y),(z)。
输出格式
共(T)行对应(T)个询问。
样例输入
2
3 5 2
400 200 100
样例输出
56
282195585
样例解释
Cirno都能算的出来
数据范围
对于(10%)的数据 (T=10,x,y,z<=10)。
对于(30%)的数据 (T=10,x,y,z<=1000)。
对于另外(20%)的数据满足(T=1,x,y,z<=1000000)。
对于另外(10%)的数据满足(x=0)。
对于另外(10%)的数据满足(x=1)。
对于(100%)的数据满足(T<=10000,0<=x,y,z<=1000000),且保证(y>=z)
前置芝士
范德蒙德卷积
(egin{aligned}sum_{i=0}^k{C_n^iC_{m}^{k-i}}=C_{n+m}^{k}end{aligned})
从意义上理解即可,也就是从数量为(n)和(m)的两个堆中一共选择(k)个物品这两个堆在实际意义上也可以不存在。
有了这个公式你就可以一步得到结论,最后就求(egin{aligned}C_{x+y}^{x+z}\%998244353end{aligned})即可
常用结论:(egin{aligned}sum_{i=1}^n{C_n^iC_{n}^{i-1}}=C_{2n}^{n-1}end{aligned})
简单的证明:
(inom{2n}{n-1}=sum_{i=0}^{n}{inom{n}{i}inom{n}{n-1-i}}=sum_{i=0}^{n}{inom{n}{i}inom{n}{i+1}}=sum_{i=1}^{n}inom{n}{i}inom{n}{i-1})
(egin{aligned}sum_{i=0}^n{C_n^i}^2=C_{2n}^{n}end{aligned})
(egin{aligned}sum_{i=1}^m{C_n^iC_m^{i}}=C_{n+m}^{m}end{aligned})
读者自证不难
#include<bits/stdc++.h>
#define LL long long
using namespace std;
/*Grievous Lady*/
template <typename T> void read(T & t){
t = 0;int f = 1;char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')f =- 1;ch = getchar();}
do{t = t * 10 + ch - '0';ch = getchar();}while(ch >= '0' && ch <= '9');t *= f;
}
#define mod 998244353
const int kato = 1e6 + 1;
LL yuni[kato * 2];
inline LL quick_pow(LL a , LL b){
LL res = 1;
for(; b ; b >>= 1 , a = a * a % mod){
if(b & 1){
res = res * a % mod;
}
}
return res % mod;
}
inline LL c(LL x , LL y){
if(x < y){
return 0;
}
return yuni[x] * quick_pow(yuni[y] * yuni[x - y] % mod , mod - 2) % mod;
}
inline LL lucas(LL x , LL y){
if(y == 0) return 1;
return c(x % mod , y % mod) * lucas(x / mod , y / mod) % mod;
}
LL t , x , y , z;
inline int Ame_(){
read(t);
yuni[0] = yuni[1] = 1;
for(int i = 1;i <= 2 * kato;i ++){
// cout << "QAQ" << "
";
yuni[i] = (yuni[i - 1] * i) % mod;
}
// cout << yuni[3] << ' ' << yuni[5] << ' ';
for(; t --> 0 ;){
LL ans = 0;
read(x);read(y);read(z);
ans = lucas(x + y , x + z);
printf("%lld
" , ans % mod);
}
return 0;
}
int Ame__ = Ame_();
int main(){;}