题目传送门

题意:给出n,m,k,用m个0到n-1的数字凑出k,问方案数,mod一个值。

题目思路:

首先如果去掉数字范围的限制,那么就是隔板法,先复习一下隔板法。

①k个相同的小球放入m个不同的盒子,每个盒子不为空的种类数:k-1个空隙中插入m-1个板子,C(k-1, m-1)

②k个相同的小球放入m个不同的盒子,可以允许有的盒子为空种类数:我们再加上m个球,按照①式不为空求解,因为分割完后,每个盒子减去1,就是当前问题的解,即:C(k-1+m, m-1);

而现在有了n这个限制,也就是说之前算出来的答案中有非法的情况,即至少有一个盒子里面有至少n个球,也就是说我需要减去这些非法的方案,当至少有一个盒子里面是至少n个球时,这样的方案数是C(m,1)*C(k-1+m-n,m-1)。(这个式子怎么理解呢,第一步,先从m个盒子中选出一个盒子,放上n个小球,确保这个方案非法,第二步,把剩下的球随机放入m个盒子中,并且有盒子可以不放球,这就是前后两个式子的含义)。但是!如果只是减去这个式子,那么会删的太多,为什么呢?

举个例子,如果我第一步往一号盒子放了n个球,然后随机放的时候往2号盒子放了n个球,这种方案和第一步往2号盒子里放n个球,然后随机放的时候往一号盒子里放n个球,情况是不是一样呢,也就是说,C(m,1)*C(k-1+m-n,m-1)这个式子包含了这两种相同的方案,那我如果减去这个是不是就重复减了呢?重复减怎么办呢,那就加上这个,而三个n的情况是不是又多余了呢,那就减去。于是就得到了一个容斥的式子。

最后的答案就是  C(k-1+m, m-1)+  (-1)^i   *  C(m,i)*  C(k-1+m-i*n,m-1),i从1到m。

计算组合数的地方要用逆元,阶乘要预处理,而逆元的话用费马小定理加减枝似乎也可以过,但为了练习前几天学的线性逆元方程,就使用了这个来做。特别的是,如果inv[i]表示的是i的逆元,那么不可以直接用inv[A[i]]来表示i的阶乘的逆元,因为i的阶乘A[i]可能很大,会爆数组,所以要用jc[i]表示i的阶乘的逆元,jc[i]=jc[i-1]*inv[i]%mod;然后就可以啦。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string.h>
#include<sstream>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#define CLR(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define eps 1e-9
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=200010;
ll mod=998244353;
int T;
ll n,m,k;
ll A[maxn];
ll inv[maxn],jc[maxn];
void initinv(){
inv[1]=1;
for(int i=2;i<=200010;i++){
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
}
ll c(ll m1,ll n1){
if(n1<m1)return 0;
return A[n1]*jc[m1]%mod*jc[n1-m1]%mod;
}
int main(){
initinv();
A[0]=1;
jc[0]=1;
for(int i=1;i<=200000;i++){
A[i]=A[i-1]*i%mod;
jc[i]=jc[i-1]*inv[i]%mod;
}
cin>>T;
while(T--){
scanf("%lld%lld%lld",&n,&m,&k);
if(k==0){//这些是简单的减枝 没有也能过
printf("1\n");
continue;
}
if(k>m*(n-1)){
printf("0\n");
continue;
}
if(k<n){
ll ans=c(k,m+k-1);
printf("%lld\n",ans);
}else{
ll ans=0;
int flag=-1;
ans+=c(m-1,m+k-1);
for(int i=1;i<=m;i++){
ans+=flag*c(i,m)*c(m-1,m+k-i*n-1)%mod;
ans=(ans+mod)%mod;
flag*=-1;
}
printf("%lld\n",ans);
}
}
}

Character Encoding

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

Total Submission(s): 1774    Accepted Submission(s): 686

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

Source

2018 Multi-University Training Contest 8

最新文章

  1. 用Javascript(js)进行HTML转义工具(处理特殊字符显示)
  2. 关于lambda表达式的一些学习——基于谓词筛选值序列
  3. Redis的AOF是怎么实现的
  4. python:how does subclass call baseclass&#39;s __init__()
  5. JavaWeb学习----Cookie实现记住密码的功能
  6. DBA必备:MySQL数据库常用操作和技巧
  7. hdu 4268 multiset+贪心
  8. freebsd 显示中文
  9. Socket与TcpClient的区别(转载)
  10. 10个专属于移动app开发者的最佳移动JavaScript框架
  11. (转)SQL利用Case When Then多条件判断
  12. MSSQL 日期操作函数 总结
  13. 禁用 VS2010 的 vcpkgsrv.exe 运行
  14. 利用pyinotify监控文件内容,像tailf命令但比它更强
  15. 201521044091 《Java程序设计》第5周学习总结
  16. 1.7 理解dropout
  17. 常见Css样式
  18. CSS解决无空格太长的字母,数字不会自动换行的问题
  19. Nexus3.x安装及配置
  20. djiango 虚拟环境与项目创建

热门文章

  1. struts2学习笔记(4)接收参数
  2. CheckBoxJS选中与反选得到Value
  3. python 删除正在for循环遍历的list正确做法
  4. Luogu 3759 [TJOI2017]不勤劳的图书管理员
  5. Umbraco中获取UmbracoContext
  6. 监控linux系统的简易脚本
  7. java求几个数字的和输出详细步骤
  8. c#设计模式-单例模式【转】
  9. Chrom去掉&quot;未选择任何文件&quot;
  10. 动态绑数据(Repeater控件HeaderTemplate和ItemTemplate)