【题解】Hikari与组合数

题目背景

(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(){;}
原文地址:https://www.cnblogs.com/Ame-sora/p/13419536.html