Character Encoding

 

Problem Description

In computer science, a character is a letter, a digit, a punctuation mark or some other similar symbol. Since computers can only process numbers, number codes are used to represent characters, which is known as character encoding. A character encoding system establishes a bijection between the elements of an alphabet of a certain size n and integers from 0 to n−1. Some well known character encoding systems include American Standard Code for Information Interchange (ASCII), which has an alphabet size 128, and the extended ASCII, which has an alphabet size 256.

For example, in ASCII encoding system, the word wdy is encoded as [119, 100, 121], while jsw is encoded as [106, 115, 119]. It can be noticed that both 119+100+121=340 and 106+115+119=340, thus the sum of the encoded numbers of the two words are equal. In fact, there are in all 903 such words of length 3 in an encoding system of alphabet size 128 (in this example, ASCII). The problem is as follows: given an encoding system of alphabet size n where each character is encoded as a number between 0 and n−1 inclusive, how many different words of length m are there, such that the sum of the encoded numbers of all characters is equal to k?

Since the answer may be large, you only need to output it modulo 998244353.

 

 

Input

The first line of input is a single integer T (1≤T≤400), the number of test cases.

Each test case includes a line of three integers n,m,k (1≤n,m≤105,0≤k≤105), denoting the size of the alphabet of the encoding system, the length of the word, and the required sum of the encoded numbers of all characters, respectively.

It is guaranteed that the sum of n, the sum of m and the sum of k don't exceed 5×106, respectively.

Output

For each test case, display the answer modulo 998244353 in a single line.

Sample Input

4 2 3 3 2 3 4 3 3 3 128 3 340

Sample Output

1 0 7 903

异曲同工之妙

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;


const int maxn=2e5+10;
const int mod=998244353;
//大组合数取模(当n,m大于p的时候也能用)
//begin
ll pow_mod(ll base,int n,int mod){
	ll ans=1;
	while(n){
		if(n&1)ans=(ans*base)%mod;
		base=(base*base)%mod;
		n>>=1;
	}
	return ans%mod;
}
ll F[maxn];
void init(){
	F[0]=1;for(int i=1;i<maxn;i++)F[i]=F[i-1]*(ll)i%mod;
}
//注意求逆元的时候用费马小定理前提:mod是素数
ll C(ll n,ll k){
     ll ans=(F[k]*F[n-k])%mod;
	 ans=pow_mod(ans,mod-2,mod);
	 return (ans*F[n])%mod;
}
ll Lucas(ll n,ll m){
	return m==0?1:(C(n%mod,m%mod)*Lucas(n/mod,m/mod))%mod;
}
//end


/*
当时知道可重复排列的m个数 和为k 的全排列公式,但是没有限制
后来我想过是不是可以减掉不合法的,所以我们当时就想直接 n*C(k+m-1-n,m-1),也就是减掉至少有一个超过n的,因为留着一个n,给谁都行
发现样例都过不了,然后GG
我们可以这样考虑,就是把第一个数字>=n的数量记为A,第二个记为B,。。。第m个记为M,所以要从全集里减掉>=n的所有的数量
所以也就是求|A并B并C...并M|的数量,然后就是容斥了 -|A|-|B|-...|M|+|AB|+|AC|...+|LM|-|ABC|-|ABD|-....
然后从总数里面减掉上面最后的结果就好了。当时只是想横着删掉,就是没想到竖着分类
*/

int main(){
    init();
    int T;
    scanf("%d",&T);
    while(T--){
        ll n,m,k;
        scanf("%lld %lld %lld",&n,&m,&k);
        ll ans=Lucas(k+m-1,m-1);
        int d=k/n;
        for(int i=1;i<=min(m,(ll)d);i++){//1.最多只有m 2.合法的取值
            ll sig=1;
            if(i&1)sig=-1;
            ll tmp=Lucas(m,i)*Lucas(k+m-1-i*n,m-1)%mod;
            ans=(ans+sig*tmp+mod)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值