标签:blog io os sp for on div log ef
//组合数取模
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MaxM = 10 + 5, MaxPi = 100000 + 5;
int n, m, Top;
int W[MaxM], Ci[MaxPi], Pi[MaxPi], Phi[MaxPi], PiCi[MaxPi];
typedef long long LL;
LL P, Q, Ans, Sum;
LL f[MaxPi], MI[MaxPi], PI[MaxPi];;
LL Pow(LL a, LL b, LL Mod) {
a %= Mod; b %= Mod;
LL ret = 1, f = a;
while (b) {
if (b & 1) {
ret *= f;
ret %= Mod;
}
b >>= 1;
f *= f;
f %= Mod;
}
return ret;
}
struct ES
{
LL u, t;
};
ES Solve(int num, int Pi_e, int PiCi_e) {
ES ret;
ret.u = 0;
ret.t = 1;
while (num) {
ret.u += num / Pi_e;
ret.t *= Pow(f[PiCi_e - 1], num / PiCi_e, PiCi_e);
ret.t %= PiCi_e;
ret.t *= f[num % PiCi_e];
ret.t %= PiCi_e;
num /= Pi_e;
}
return ret;
}
LL C1(int a, int b, int Pi_e, int PiCi_e, int Phi_e) {
f[0] = 1; f[1] = 1;
for (int i = 2; i <= PiCi_e - 1; i++) {
if (i % Pi_e == 0) f[i] = f[i - 1];
else f[i] = f[i - 1] * i % PiCi_e;
}
LL ret, uu, t1, t2, t3;
ES e1, e2, e3;
e1 = Solve(a, Pi_e, PiCi_e);
e2 = Solve(a - b, Pi_e, PiCi_e);
e3 = Solve(b, Pi_e, PiCi_e);
uu = e1.u - (e2.u + e3.u);
t1 = e1.t; t2 = e2.t; t3 = e3.t;
ret = Pow(Pi_e, uu, PiCi_e);
ret *= t1; ret %= PiCi_e;
ret *= Pow(t2, Phi_e - 1, PiCi_e); ret %= PiCi_e;
ret *= Pow(t3, Phi_e - 1, PiCi_e); ret %= PiCi_e;
return ret;
}
LL C2(int a, int b) {
LL ret;
ret = 0;
for (int i = 1; i <= Top; i++) {
ret += (C1(a, b, Pi[i], PiCi[i], Phi[i]) * ((MI[i] * PI[i]) % P)) % P;
ret %= P;
}
return ret;
}
int main()
{
cin >> P >> n >> m;
Sum = 0;
for (int i = 1; i <= m; i++) {
scanf("%d", &W[i]);
Sum += (LL)W[i];
}
if (Sum > n) {
printf("Impossible\n");
return 0;
}
Top = 0;
Q = P;
int SQRTQ = (int)sqrt(Q * 1.0);
for (int i = 2; i <= SQRTQ; i++) {
if (Q % i != 0) continue;
Pi[++Top] = i;
PiCi[Top] = 1;
Ci[Top] = 0;
while (Q % i == 0) {
++Ci[Top];
PiCi[Top] *= i;
Q /= i;
}
Phi[Top] = PiCi[Top] / i * (i - 1);
MI[Top] = P / PiCi[Top];
PI[Top] = Pow(MI[Top], Phi[Top] - 1, PiCi[Top]);
}
if (Q > 1) {
Pi[++Top] = Q;
PiCi[Top] = Q;
Ci[Top] = 1;
Phi[Top] = Q - 1;
MI[Top] = P / PiCi[Top];
PI[Top] = Pow(MI[Top], Phi[Top] - 1, PiCi[Top]);
}
Ans = 1;
for (int i = 1; i <= m; i++) {
Ans *= C2(n, W[i]);
Ans %= P;
n -= W[i];
}
cout << Ans << endl;
// printf("%I64d\n", C2(n, m));
return 0;
}
标签:blog io os sp for on div log ef
原文地址:http://www.cnblogs.com/F-Magician/p/4129183.html