题目叙述很啰嗦,可以简化为:n个球[1-1e5],放到m个不同的桶里,一共多少种不同的放法。【桶里可以不放】
------------------------------------------------------------------------------------------------
解C(n+m-1, m-1)
由于m,n可能很大,所以需要用逆元。扩展欧几里得。
#include <set> #include <map> #include <stack> #include <queue> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> typedef long long LL; using namespace std; const int N = 200001; LL MOD = 1e9 + 7; LL F[N], Inv[N]; LL exgcd(LL a, LL b, LL& x, LL& y){ if (b == 0){ x = 1, y = 0; return a; } else{ auto gcd = exgcd(b, a%b, y, x); y -= (a / b) * x; return gcd; } } int main(){ LL n, k; cin >> n >> k; int left = n - k, last = MOD, seg = 0; n += MOD; for (int i = 0; i < left; ++i){ int val; scanf("%d", &val); if (val>last){ last = val; } else{ ++seg; n -= last; last = val; } } n -= last; if (n < 0){ puts("No"); } else{ F[0] = 1; for (int i = 1; i < N; ++i){ F[i] = (i * F[i - 1]) % MOD; } LL nouse; exgcd(F[N - 1], MOD, Inv[N-1], nouse); while (Inv[N - 1] < 0) Inv[N - 1] += MOD; for (int i = N - 2; i; --i){ Inv[i] = (Inv[i + 1] * (i + 1)) % MOD; } std::cout << (F[n + seg - 1] * Inv[n]) % MOD*Inv[seg - 1] % MOD << std::endl; //C(n+seg-1,seg-1); } }