2018 Multi-University Training Contest 8 &&HDU6397 Character Encoding【数论-组合数学|容斥】

Character Encoding

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)

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 × 10 6 , respectively.

Output

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

Examples

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

Output
1
0
7
903

扫描二维码关注公众号,回复: 9888605 查看本文章

【题目链接】 Character Encoding

【题意】
i = 1 m x i == k ( 0 <= x i <= n 1 ) 的方案数

【思路】

我们先考虑 x i 没有上界的情况,这是最为经典的放球问题的插板法(可以参考 此链接
结果为 C k + m 1 m 1
然后我们现在假定其中有 x 个数它的范围是 x >= n ,那么我们需要把这些数都减去 n ,那么就有满足上面的公式了,但是这个时候总和会减小,为 k x n 其方案数为 C k x n + m 1 m 1

显然我们需要把这一部分减去,但是由于不同的 x 会有重复计算,所以要用到容斥。
x 为偶数的时候加上方案数,为奇数的时候减去方案数
故最终的答案为

i = 0 k n ( 1 ) i C m i C k i n + m 1 m 1

#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)

typedef long long ll;
const int maxn = 200005;
const ll mod=998244353;
const ll INF = 1e18;
const double eps = 1e-9;

int n,m,k;
ll fac[maxn],inv[maxn];

ll fast_mod(ll a,ll n,ll Mod)
{
    ll ans=1;
    while(n)
    {
        if(n&1) ans=(a*ans)%Mod;
        a=(a*a)%Mod;
        n/=2;
    }
    return ans;
}

void init()
{
    fac[0]=1;
    for(int i=1;i<maxn;i++) fac[i]=(fac[i-1]*i)%mod;
    inv[maxn-1]=fast_mod(fac[maxn-1],mod-2,mod);
    for(int i=maxn-2;i>=0;i--) inv[i]=(inv[i+1]*(i+1))%mod;
}

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

int main()
{
    init();
    rush()
    {
        scanf("%d%d%d",&n,&m,&k);
        ll ans=0;
        int up=k/n;
        for(int i=0;i<=up;i++)
        {
            ll tmp=1;
            if(i&1) tmp=mod-1;
            ans+=(tmp*C(m,i)%mod*C(m+k-1-n*i,m-1)%mod);
            ans%=mod;
        }
        printf("%lld\n",ans);
    }
}
发布了259 篇原创文章 · 获赞 100 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/my_sunshine26/article/details/81740606
今日推荐