AT_abc425_e 题解

前言

时隔1个月,我又来写题解了~~~~~。
这个题目其实不是很难,挺简单的,考场上思路方向错了。

题目传送门:

戳我

题面:

你会获得一个正整数\(N\),和一个长度为\(N\)的正整数数组:\(C = (C_1,C_2,...,C_N)\)
你需要求出的是:所有满足以下条件的数组的个数模上给定的正整数\(M\)

  • 数组中所有的数字均为\(1\)\(N\)中的一个数。

  • 对于\(i = 1,2,...,N\),数字\(i\)在数组中出现正好\(C_i\)次。
    每次会给\(T\)组数据,你需要把每个数据的答案都求出来,\(M\)在这\(T\)组数据中都是一样的。

  • \(1 \leq T \leq 10^5\)

  • \(2 \leq M \leq 10^9\)

  • \(1 \leq N\)

  • \(1 \leq C_i\)

  • \(\displaystyle{\sum_{i=1}^{N} C_i} \leq 5000\)

  • 所有的\(T\)组数据中,所有\(N\)的和不超过\(3 \times 10^5\)

  • 所有的输入都是整数。

题解

首先们可以把题目稍微简化一下。

那么这道题就是把\(C_1个1,C_2个2,C_3个3,...,C_N个N\)全部拼起来的方案数,总长度是\(\displaystyle{\sum_{i=1}^{N} C_i}\)

我们给\(C\)求一个前缀和\(S\),即$S_i = \displaystyle{\sum_{j=1}^{i} C_j} $

那么总长度就是\(S_N\)

接下来算拼起来的方案数,可以从简单题考虑到难题。
简单题:

有15个球,除了颜色外都相同,其中有5个红球,6个蓝球,4个绿球请问有多少种排法。
这道题的做法很简单:先算15个球中选5个红球,再从剩下的10个球中选6个蓝球,最后在5个球种选4个绿球。
列式就是:\(C_{15}^5 \times C_{(15-5)}^6 \times C_{(15-5-6)}^4\)

那么类比到这道题
可以看出答案就是 \(\displaystyle{\prod_{i=1}^{N} \Large{C}_{\small{(S_N-S_{i-1})}}^{\small{C_i}}}\)

\((S_N-S_{i-1})\)就是算取\(C_i\)个数字(也就是上面的球)前剩下多少。

那么这道题就基本解决了。。。。。等一下!如果我们直接每次算\(\Large{C}_{\small{(S_N-S_{i-1})}}^{\small{C_i}}\)会时间爆掉,怎么办呢?

我们可以提前预处理出每一个\(C_i^j\)来,因为\((S_N-S_{i-1})\)\(C_i\)不超过5000,所以我们可以用\(5000^2\)的时间把\(C_i^j\)预处理出来。而且由于\(M\)在所有的组中是一样的,所以可以直接在输入后去预处理(预处理用杨辉三角),这样就可以不爆时间了。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int c[300001];
int C[5001][5001];
int s[300001];
signed main()
{
    int t, m;
    cin >> t >> m;
    C[0][0] = 1;
    for (int i = 1; i <= 5000; i++) // 预处理
    {
        C[i][0] = 1;
        for (int j = 1; j <= i; j++)
        {
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % m; // 杨辉三角
        }
    }
    while (t--)
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> c[i];
            s[i] = s[i - 1] + c[i]; // 求前缀和
        }
        int ans = 1;
        for (int i = 1; i <= n; i++)
        {
            ans = ans * C[s[n] - s[i - 1]][c[i]] % m; // 按照公式,求答案。
        }
        cout << ans << endl;

    }
    return 0;
}


完结撒花~~~~

posted @ 2025-09-30 16:35  MichaelZeng  阅读(12)  评论(0)    收藏  举报