hdu6397 Character Encoding 隔板法+容斥原理+线性逆元方程
题意:给出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
hdu6397 Character Encoding 隔板法+容斥原理+线性逆元方程的更多相关文章
- CF451E Devu and Flowers (隔板法 容斥原理 Lucas定理 求逆元)
Codeforces Round #258 (Div. 2) Devu and Flowers E. Devu and Flowers time limit per test 4 seconds me ...
- hdu6397 Character Encoding 母函数解约束条件下多重集
http://acm.hdu.edu.cn/showproblem.php?pid=6397 原问题的本质是问m个元素的多重集S,每一种类型的对象至多出现n-1次的S的k组合的个数是多少? 等价于 x ...
- A - Character Encoding HDU - 6397 - 方程整数解-容斥原理
A - Character Encoding HDU - 6397 思路 : 隔板法就是在n个元素间的(n-1)个空中插入k-1个板,可以把n个元素分成k组的方法 普通隔板法 求方程 x+y+z=10 ...
- 逆元 组合A(n,m) C(n,m)递推 隔板法
求逆元 https://blog.csdn.net/baidu_35643793/article/details/75268911 int inv[N]; void init(){ inv[] = ; ...
- hdu 6397 Character Encoding (生成函数)
Problem Description In computer science, a character is a letter, a digit, a punctuation mark or som ...
- 多校 HDU 6397 Character Encoding (容斥)
题意:在0~n-1个数里选m个数和为k,数字可以重复选: 如果是在m个xi>0的情况下就相当于是将k个球分割成m块,那么很明显就是隔板法插空,不能为0的条件限制下一共k-1个位置可以选择插入隔板 ...
- 51Nod 1509 加长棒(隔板法)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1509 思路: 直接去解可行的方法有点麻烦,所以应该用总的方法去减去不可行 ...
- light oj 1102 - Problem Makes Problem组合数学(隔板法)
1102 - Problem Makes Problem As I am fond of making easier problems, I discovered a problem. Actuall ...
- 使用英文版eclipse保存代码,出现some characters cannot be mapped using "Cp1251" character encoding.
some characters cannot be mapped using "Cp1251" character encoding. 解决办法:方案一: eclipse-> ...
随机推荐
- hadoop job -kill 与 yarn application -kii(作业卡了或作业重复提交或MapReduce任务运行到running job卡住)
问题详情 解决办法 [hadoop@master ~]$ hadoop job -kill job_1493782088693_0001 DEPRECATED: Use of this script ...
- Java构造函数中调用构造函数
在Java中,当为一个类创建了多个构造函数时,有时想在一个构造函数中调用另一个构造函数以减少代码量.这时可以使用this关键字来实现. 通常,当使用this关键字时,它意味着"这个对象&qu ...
- Etyma01 ced ceed cess
一. etyma ['ɛtə,mə] ced.ceed.cess -> go -> 行走,前进 二.for instance 1. precede=pre+ced+e pre- 在前 2. ...
- Java_枚举类
枚举类 枚举类不出来的时候只能如下写代码 //Student.java package cn.itcast.enumeration; public class Student { private St ...
- C++笔记--异常
引言 异常,让一个函数可以在发现自己无法处理的错误时抛出一个异常,希望它的调用者可以直接或者间接处理这个问题.而传统错误处理技术,检查到一个局部无法处理的问题时: 1.终止程序(例如atol,atoi ...
- 《Linux内核设计与实现》读书笔记(七)- 中断处理
中断处理一般不是纯软件来实现的,需要硬件的支持.通过对中断的学习有助于更深入的了解系统的一些底层原理,特别是驱动程序的开发. 主要内容: 什么是中断 中断类型 中断相关函数 中断处理机制 中断控制方法 ...
- android报错:org.ksoap2.SoapFault cannot be cast to org.ksoap2.serialization.SoapObject
今天在写一个webservice时一直报错,报Caused by: java.lang.ClassCastException: org.ksoap2.SoapFault cannot be cast ...
- Html5代码片段收集
HTML5 启动模板 当启动一个新的项目的时候,你需要一个启动模板.这里是一个简洁干净的模板,可以作为 HTML5 项目的基础. <!DOCTYPE html> <html> ...
- 解决:kali linux 在vmware 虚拟机中使用bridge模式上网的问题
安装kali后,使用独立ip上网,但是设置bridge模式后依然上不了网,后来查了好多资料才解决。 能ping通网页,能ping通DNS,就是不能打开网页。 最后的原因是主机的防火墙拦截,把防火墙关了 ...
- 微信小程序小结(5) -- 常用语法
在 pages 字段的第一个页面就是这个小程序的首页(打开小程序看到的第一个页面). Page生命周期 属性 类型 描述 onLoad Function 生命周期函数--监听页面加载.一个页面只会调用 ...