题解:[省选联考 2020 A 卷] 组合数问题
题解——[省选联考 2020 A 卷] 组合数问题
题目描述
计算
\(1\le n, x, p \le 10^9, 0\le a_i\le 10^9, 0\le m \le \min(n,1000)\)。
思路
其实思路并不难,只有最后一步有点小思维。
\( \begin{aligned} &\sum_{k=0}^{n}f(k)x^k\binom{n}{k} \\ &=\sum_{k=0}^{n}\sum_{i=0}^{m}a_ik^ix^k\binom{n}{k} \\ &=\sum_{i=0}^{m}a_i\sum_{k=0}^{n}x^k\binom{n}{k}\sum_{j=0}^{i}{\binom{k}{j}{i \brace j}j!} \\ &=\sum_{i=0}^{m}a_i\sum_{j=0}^{i}{i \brace j}j!\sum_{k=0}^{n}{\binom{k}{j}\binom{n}{k}x^k} \\ &=\sum_{i=0}^{m}a_i\sum_{j=0}^{i}\binom{n}{j}{i \brace j}j!\sum_{k=0}^{n}{\binom{n-j}{k-j}x^k} \\ &=\sum_{i=0}^{m}a_i\sum_{j=0}^{i}\binom{n}{j}{i \brace j}j!x^j\sum_{k=0}^{n}{\binom{n-j}{k-j}x^{k-j}} \\ &=\sum_{i=0}^{m}a_i\sum_{j=0}^{i}A_{n}^{j}{i \brace j}x^j(1+x)^{n-j} \end{aligned} \)
其实最后一步我还有一种十分诡谲的做法,但是太麻烦就不写了。
不过还有一个小技巧,尽管所有的数都缩到了 \(m\) 里,但是这个 \(A_{n}^{j}\) 并没有,但不过可以预处理出来每次 \(A_{n}^{j}=A_{n}^{j-1}(n-j+1)\) 就好了。
code
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <bitset>
#include <set>
#include <map>
#include <cstdio>
#include <cassert>
#include <iomanip>
using namespace std;
#define lid id << 1
#define rid id << 1 | 1
#define emp emplace_back
#define endl '\n'
#define fi first
#define se second
const int N = 1e3 + 7;
#define int long long
using ll = long long;
using ld = long double;
using pii = pair <int, int>;
int a[N], s[N][N], mod;
int qpow(int x, int b)
{
int res = 1;
while (b)
{
if (b & 1) res = res * x % mod;
x = x * x % mod;
b >>= 1;
}
return res;
}
int A[N];
signed main()
{
// freopen("data.in", "r", stdin); freopen("data.out", "w", stdout);
ios :: sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, x, m; cin >> n >> x >> mod >> m;
s[0][0] = 1;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= m; j++)
{
s[i][j] = (s[i - 1][j - 1] + s[i - 1][j] * j) % mod;
}
}
A[0] = 1;
for (int i = 1; i <= m; i++) A[i] = A[i - 1] * (n - i + 1) % mod;
int ans = 0, res = 0;
for (int i = 0; i <= m; i++)
{
cin >> a[i];
res = 0;
for (int j = 0; j <= i; j++)
{
res += A[j] * s[i][j] % mod * qpow(x, j) % mod * qpow(1 + x, n - j) % mod;
res %= mod;
}
ans += a[i] * res;
ans %= mod;
}
cout << ans;
return 0;
}

浙公网安备 33010602011771号