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;
}

猜你喜欢

转载自blog.csdn.net/qq_36424540/article/details/81709729