HDU 6397(组合数学-容斥-逆原-2018多校第八场1001)

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <list>
#define INF 0x3f3f3f3f
#define maxn 105000
#define maxnn 6000
#define juzheng 300
#define line cout << "-------------------------" << endl;
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define fill_(a,b,n) fill(a,a + n,b)
#define esp 1e-9

#define ri(n) scanf("%d",&n)
#define ri2(a,b) scanf("%d %d",&a,&b)
#define ri3(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define rd(n) scanf("%lf",&n)
#define rd2(a,b) scanf("%lf %lf",&a,&b)
#define rd3(a,b,c) scanf("%lf %lf %lf",&a,&b,&c)
#define rl(n) scanf("%lld",&n)
#define rl2(a,b) scanf("%lld %lld",&a,&b)
#define rl3(a,b,c) scanf("%lld %lld %lld",&a,&b,&c)
#define rui(n) scanf("%u",&n)
#define rui2(a,b) scanf("%u %u",&a,&b)
#define rui3(a,b,c) scanf("%u %u %u",&a,&b,&c)
#define rs(str) scanf("%s",str)
#define pr(n) cout << n << endl
#define debug(str,x) cout << str << ":" << x << endl
#define ll long long
#define int64 __int64
#define ui unsigned int

using namespace std;

const ll mod = 998244353;
const ll N = maxn * 2;

//Date:2018-8-15
//Author:HarryBlackCat

ll fac[N],inv[N];

ll quickpow(ll a,ll b) {
	ll ans=1;
	while(b) {
		if(b&1) {
			ans=(ans*a)%mod;
		}
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}

ll get_inv(ll x,ll MOD) {
	return quickpow(x,MOD - 2);
}

void init() {
	fac[0]=1;
	for (ll i = 1; i < N; i++)
		fac[i] = fac[i - 1] * i % mod;
	inv[N - 1]=get_inv(fac[N - 1],mod);
	for(ll i=N-2; i>=1; i--) {
		inv[i]=(1LL*inv[i+1]*(i+1))%mod;
	}
}

ll C(ll n, ll m) {
	if(m == 0 || n == m)
		return 1;
	return (fac[n] * (inv[m] % mod) % mod * (inv[n - m] % mod)) % mod;
}

ll add(ll a) {
	while (a < 0) {
		a += mod;
	}
	return a % mod;
}

ll n,m,k;

int main() {
	//cin.sync_with_stdio(false);//降低cin,cout时间
	int t;
	init();
	while(~ri(t)) {
		while(t--) {
			rl3(n,m,k);

			if((n - 1) * m < k) {
				puts("0");
				continue;
			}

			ll ans = 0;
			ll sum = k + m - 1;
			ll i = 1;
			ll j = 0;

			while(sum > 0) {
				if(sum < m - 1)
					break;
				ans = (ans + add(i * C(m,j)) * C(sum,m - 1));
				ans %= mod;
				sum -= n;
				j++;
				i *= -1;
			}

			printf("%lld\n",ans);
		}
	}
	return 0;
}

//100
//100000 100000 100000
//996837032

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值