zoukankan      html  css  js  c++  java
  • hdu 6397 Character Encoding (生成函数)

    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
     

    Solution

    这题有两种解法,一是std给的容斥,二是生成函数。

    在0..n-1中选择m个数(可重复)使之和为k,这是一类整数拆分数问题,当n没有限制时,由隔板法可以得到ans=C(k+m-1,m-1)。好了容斥解法我还没看明白,容斥先鸽一割

    进入正题谈谈生成函数,此题中,对于0..n-1这样一个序列每次它可以是选择其中一个数,其用生成函数表现为(1+x+x^2...+x^(n-1)),幂次即代表选择的是哪个数

    那么对于m次选择,其随机可重复组合的生成函数g(x)=(1+x+x^2+...+x^(n-1))^m,生成函数中的幂级数是以形式幂级数理论为基础的,也就是说默认级数收敛。

    f(x)=1+x+x^2+...+x^(n-1) => f(x)=(1-x^n)/(1-x), g(x)=(1-x^n)^m*(1-x)^(-m),对于这样一个式子,我们对前面一部分二项式展开可得


     1 #include <bits/stdc++.h>
     2 #define lson rt << 1, l, mid
     3 #define rson rt << 1 | 1, mid + 1, r
     4 using namespace std;
     5 using ll = long long;
     6 using ull = unsigned long long;
     7 using pa = pair<int, int>;
     8 using ld = long double;
     9 ll n, m, k;
    10 const int maxn = 3e5 + 10;
    11 const int mod = 998244353;
    12 template <class T>
    13 inline T read(T &ret)
    14 {
    15     int f = 1;
    16     ret = 0;
    17     char ch = getchar();
    18     while (!isdigit(ch))
    19     {
    20         if (ch == '-')
    21             f = -1;
    22         ch = getchar();
    23     }
    24     while (isdigit(ch))
    25     {
    26         ret = (ret << 1) + (ret << 3) + ch - '0';
    27         ch = getchar();
    28     }
    29     ret *= f;
    30     return ret;
    31 }
    32 template <class T>
    33 inline void write(T n)
    34 {
    35     if (n < 0)
    36     {
    37         putchar('-');
    38         n = -n;
    39     }
    40     if (n >= 10)
    41     {
    42         write(n / 10);
    43     }
    44     putchar(n % 10 + '0');
    45 }
    46 ll fac[maxn], inv[maxn];
    47 void init()
    48 {
    49     fac[0] = fac[1] = 1;
    50     inv[0] = inv[1] = 1;
    51     for (ll i = 2; i < maxn; i++)
    52     {
    53         fac[i] = fac[i - 1] * i % mod;
    54         inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
    55     }
    56     for (ll i = 2; i < maxn; i++)
    57         inv[i] = inv[i - 1] * inv[i] % mod;
    58 }
    59 ll C(ll x, ll y)
    60 {
    61     if (y > x)
    62         return 0;
    63     if (y == 0 || x == 0)
    64         return 1;
    65     return fac[x] * inv[y] % mod * inv[x - y] % mod;
    66 }
    67 int main(int argc, char const *argv[])
    68 {
    69     ios::sync_with_stdio(false);
    70     cin.tie(0);
    71     cout.tie(0);
    72     int t;
    73     init();
    74     cin >> t;
    75     while (t--)
    76     {
    77         cin >> n >> m >> k;
    78         ll ans = 0;
    79         if (k == 0)
    80             ans = 1;
    81         else if ((n - 1) * m < k)
    82             ans = 0;
    83         else
    84         {
    85             int c = min(k / n, m);
    86             for (int i = 0; i <= c; i++)
    87             {
    88                 if (i % 2 == 0)
    89                     ans = (ans + C(m, i) * C(k - i * n + m - 1, m - 1) % mod) % mod;
    90                 else
    91                     ans = (ans - C(m, i) * C(k - i * n + m - 1, m - 1) % mod + mod) % mod;
    92             }
    93         }
    94         cout << ans << '
    ';
    95     }
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    JQuery easyui (4)Tooltip (提示组件) 组件
    JQuery easyui (3) Resizable(调整大小)组件
    洛谷 P1919 【模板】A*B Problem升级版(FFT快速傅里叶)
    2019 ACM-ICPC 上海网络赛 B. Light bulbs (差分)
    POJ 1474 Video Surveillance (半平面交)
    HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
    洛谷 P1613 跑路 (倍增 + DP + 最短路)
    POJ 1279 Art Gallery (半平面交)
    POJ 3130 How I Mathematician Wonder What You Are! (半平面交)
    POJ 2451 Uyuw's Concert (半平面交)
  • 原文地址:https://www.cnblogs.com/mooleetzi/p/11293952.html
Copyright © 2011-2022 走看看