zoukankan      html  css  js  c++  java
  • hdu-6397-容斥

    Character Encoding

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1141    Accepted Submission(s): 433


    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 n1. 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 n1 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 (1T400), the number of test cases.

    Each test case includes a line of three integers n,m,k (1n,m105,0k105), 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
       用[0,n)之间的数,填充m个有序位置使得m个位置的数的和是k的不同的方案个数。
      比赛时想到了是放球问题,但是容斥真的不会写,,dp也没调好,自闭了。
      这个问题等价于将k个小球(无差别)放入m个桶中,桶不能为空的方案个数,利用挡板法就是 :k+m个小球有k+m-1个间隙,挑出m-1个间隙插入隔板分成m块对应m个桶,再让每一块的个数减一就是实际放入的个数,这显然是等价的,方案个数就是  C(m-1,k+m-1)。
      但是有个问题是每个桶中的小球不可以大于等于n,因为[0,n)的限制,所以这个方案个数中有一部分是不合法的状态。利用容斥定理减去这些状态 f(i,j)表示包含j号桶在内至少有i个桶中的球数大于等于n的方案个数,不难得出 g(i)=SUM{ f(i,j) }=C(i,m)*C(m-1,k+m-1-i*n) , 然后对g(i)奇加偶减容斥一波。。。
      
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long 
     4 LL mod=998244353;
     5 LL inv[200010]={0,1},jc[200010]={1,1},jc_n[200010]={1,1};
     6 void init(){
     7     for(int i=2;i<=200005;++i){
     8         jc[i]=jc[i-1]*i%mod;
     9         inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    10         jc_n[i]=jc_n[i-1]*inv[i]%mod;
    11     }
    12 }
    13 LL C(LL r,LL n){
    14     if(r>n) return 0;
    15     return jc[n]*jc_n[r]%mod*jc_n[n-r]%mod;
    16 }
    17 int main()
    18 {
    19     init();
    20     int t;
    21     LL n,m,k;
    22     cin>>t;
    23     while(t--){
    24         scanf("%lld%lld%lld",&n,&m,&k);
    25         LL ans=C(m-1,k+m-1);
    26         for(LL i=1;i<=m;++i){
    27             LL res=C(i,m)*C(m-1,m+k-1-i*n)%mod;
    28             if(i%2==1) ans=(ans-res+mod)%mod;
    29             else ans=(ans+res)%mod;
    30         }
    31         printf("%lld
    ",ans);
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    通讯总线 | 串口
    shell | 命令实用汇集
    编码 | 宏定义格式化日志信息
    shell | 脚本传参
    注释 | 代码注释原则
    GCC编译优化选项介绍
    shell | 已知进程查找命令
    网络 | ifconfig 配置 IP 掩码 网关
    Makefile | 使用eclipse软件自动生成Makefile文件
    VIO系统的IMU与相机时间偏差标定
  • 原文地址:https://www.cnblogs.com/zzqc/p/9488956.html
Copyright © 2011-2022 走看看