博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 6397(容斥原理)
阅读量:5362 次
发布时间:2019-06-15

本文共 3511 字,大约阅读时间需要 11 分钟。

题面

Character Encoding

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

Total Submission(s): 689    Accepted Submission(s): 262

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

题面描述:

    给你n个大小从[0,n-1]的数字,让你在其中选取m个,使得选取的m个数的大小的和为k。

题目分析:

    这个题跟相当类似(当时没搞明白的,因此现在做题依然一(做)知(不)半(出)解(来)这次要真正的搞明白),都用到了容斥原理。

    首先,倘若题目中没有限制条件,即让我们选取m个数使得值为k的话,即题目转化成求方程组:

    中解的个数。

    按照《组合数学》中的证法,我们令,并带入式子可得:

    

    此时想象有k+m个数字‘1’排成一排,则问题等嫁祸于把这些‘1’分成m个部分,有多少种方法。

    这就相当于在k+m-1个空隙中插入m-1个隔板,根据隔板法可知,此时的方案数为

    但是题目中限制了大小只能够<n,因此在我们上诉的求法中,很显然是求多了很多方案的。因此,此时我们需要对枚举每一种不合法的条件并使用容斥原理维护整体的平衡。

    假设现在有i个数是违反了条件的(即在m个数中选i个数的方案是违反条件的),即有i个数的值是>=n的,那么显然,在此时的方程中,k是要减去i*n(去掉i个数的影响)的。故此时的方程即转化为:

    

    因此对于这种情况来说,彼时的方案数即为:

    而根据容斥原理的偶加奇减的性质,我们就可以用线性的时间求解出答案。

代码:

#include 
#define maxn 200005using namespace std;typedef long long ll;const int mod=998244353;ll inv[maxn],F[maxn],Finv[maxn];//分别代表逆元,阶乘,阶乘逆元void init(){//初始化:线性求逆元,线性求阶乘,线性求阶乘逆元 inv[1]=1; for(int i=2;i<=maxn;i++){ inv[i]=(mod-mod/i)*inv[mod%i]%mod; } F[0]=1; Finv[0]=1; for(int i=1;i<=maxn;i++){ F[i]=F[i-1]*i%mod; Finv[i]=Finv[i-1]*inv[i]%mod; }}ll C(ll n,ll m){//组合数公式 if(n<0||m<0||m>n) return 0; return F[n]*Finv[m]%mod*Finv[n-m]%mod;}int main(){ int t; init(); scanf("%d",&t); while(t--){ int n,m,k; scanf("%d%d%d",&n,&m,&k); ll res=0; for(int i=0;i*n<=k;i++){//枚举出每一种不符合条件的个数 if(i&1){//奇减偶加 res=(res-C(m,i)*C(k-i*n+m-1,m-1)%mod+mod)%mod; } else{ res=(res+C(m,i)*C(k-i*n+m-1,m-1)%mod)%mod; } } cout<
<

 

转载于:https://www.cnblogs.com/Chen-Jr/p/11007236.html

你可能感兴趣的文章
第一阶段测试题
查看>>
第二轮冲刺第五天
查看>>
图片压缩
查看>>
Hadoop-2.6.5安装
查看>>
第二讲 硬件I/O操作
查看>>
Openstack的dashboard开发之【浏览器兼容性】
查看>>
javaScript 实时获取系统时间
查看>>
ES6思维导图
查看>>
第四周作业
查看>>
20151121
查看>>
线段重叠 (思维好题)
查看>>
Codeforces Round #413 C. Fountains (线段树的创建、查询、更新)
查看>>
SBuild 0.1.5 发布,基于 Scala 的构建系统
查看>>
WordPress 3.5 RC3 发布
查看>>
DOM扩展札记
查看>>
python中的None
查看>>
Shiro权限框架使用总结
查看>>
Windows Azure 上传 VM
查看>>
SharePoint Framework 在web部件中使用第三方样式 - 将第三方样式打到包中
查看>>
阿里云OSS上传文件本地调试跨域问题解决
查看>>