OJ-Problems-Source/.ACM-Templates/TXTs/组合数学.txt

184 lines
5.8 KiB
Plaintext
Raw Normal View History

2016-11-22 09:38:35 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD> / <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> O(n^2)
//C[i][i] = C[i][0] = 1
//C[i][j] = C[i - 1][j] + C[i - 1][j - 1], 0 < j < i
const int maxc = 105;
ll C[maxc][maxc];
void calC() {
for (int i = 0; i < maxc; i++) { C[i][i] = C[i][0] = 1; }
for (int i = 2; i < maxc; i++) {
for (int j = 1; j < i; j++) { C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % M; }
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡģ O(n)
ll Com(ll n, ll m) {
if (m > n) { return 0; }
if (m > n - m) { m = n - m; }
ll ret = 1;
for (ll i = 0, j = 1; i < m; i++) {
for (ret *= n - i; j <= m && ret % j == 0; j++) { ret /= j; }
}
return ret;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡģ
//p <= 1e6 Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD>׳<EFBFBD><D7B3><EFBFBD>Ԫ O(min(n, p)) + O(1)
ll fac[M] = {1, 1}, invfac[M] = {1, 1};
void initFac(ll p) {
for (int i = 2; i < p; i++) {
fac[i] = fac[i - 1] * i % p; invfac[i] = (-invfac[p % i] * (p / i) % p + p) % p;
}
for (int i = 2; i < p; i++) { invfac[i] = invfac[i] * invfac[i - 1] % p; }
}
ll Com(ll n, ll m, ll p) {
return n < m ? 0 : fac[n] * invfac[n - m] % p * invfac[m] % p;
}
//p <= 1e9 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ O(nlogp)
ll Com(ll n, ll m, ll p) {
if (m > n) { return 0; }
if (m > n - m) { m = n - m; }
ll ret = 1;
for (ll i = 1; i <= m; i++) {
ll a = (n + i - m) % p, b = i % p;
ret = ret * a % p * powMod(b, p - 2, p) % p;
}
return ret;
}
//Lucas<61><73><EFBFBD><EFBFBD>
ll Lucas(ll n, ll m, ll p) {
if (n < m) { return 0; }
if (m == 0 && n == 0) { return 1; }
return Com(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
//<2F><>һ<EFBFBD><D2BB>Stirling<6E><67> s(p, k)
//<2F><>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD>k<EFBFBD><6B><EFBFBD>ǿ<EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>еķ<D0B5><C4B7><EFBFBD><EFBFBD><EFBFBD>
//s(p, k)<29>ĵ<EFBFBD><C4B5>ƹ<EFBFBD>ʽ<EFBFBD><CABD>s(p, k) = (p - 1) * s(p - 1, k) + s(p - 1, k - 1), 1 <= k <= p - 1
//<2F>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s(p, 0) = 0, p >= 1, s(p, p) = 1, p >= 0
const int maxs = 105;
ll S[maxs][maxs];
void calStir1() {
S[0][0] = S[1][1] = 1;
for (int i = 2; i < maxs; i++) {
for (int j = 1; j <= i; j++) { S[i][j] = ((i - 1) * S[i - 1][j] + S[i - 1][j - 1]) % M; }
}
}
//<2F>ڶ<EFBFBD><DAB6><EFBFBD>Stirling<6E><67> S(p, k)
//<2F><>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD>k<EFBFBD><6B><EFBFBD>ǿյIJ<D5B5><C4B2>ɱ<EFBFBD><C9B1><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>û<EFBFBD>б<EFBFBD><D0B1><EFBFBD>)<29><><EFBFBD>ϵķ<CFB5><C4B7><EFBFBD><EFBFBD><EFBFBD>
//k! * S(p, k)<29>ǰ<EFBFBD>p<EFBFBD><70><EFBFBD>˷ֽ<CBB7>k<EFBFBD><6B><EFBFBD>в<EFBFBD><D0B2><EFBFBD>(<28><EFBFBD><E7B1BB><EFBFBD>з<EFBFBD><D0B7><EFBFBD>)<29>ķ<EFBFBD><C4B7><EFBFBD>(<28>޿շ<DEBF>)<29>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD>
//S(p, k)<29>ĵ<EFBFBD><C4B5>ƹ<EFBFBD>ʽ<EFBFBD>ǣ<EFBFBD>S(p, k) = k * S(p - 1, k) + S(p - 1, k - 1), 1 <= k <= p - 1
//<2F>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>S(p, 0) = 0, p >= 1, S(p, p) = 1, p >= 0
const int maxs = 105;
ll S[maxs][maxs];
void calStir2() {
S[0][0] = S[1][1] = 1;
for (int i = 2; i < maxs; i++) {
for (int j = 1; j <= i; j++) { S[i][j] = (j * S[i - 1][j] + S[i - 1][j - 1]) % M; }
}
}
//Bell<6C><6C>
//B(n)<29><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>Ϊn<CEAA>ļ<EFBFBD><C4BC>ϵĻ<CFB5><C4BB>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
//B(0) = 1, B(n + 1) = sum(C(n, k) * B(k)), 0 <= k <= n
//ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵڶ<C7B5><DAB6><EFBFBD>Stirling<6E><67><EFBFBD>ĺ<EFBFBD>, <20><>B(n) = sum(S(n, k)), 1 <= k <= n
//Bell<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//a[0][0] = 1
//<2F><><EFBFBD><EFBFBD>n >= 1, a[n][0] = a[n - 1][n - 1]
//<2F><><EFBFBD><EFBFBD>m, n >= 1, a[n][m] = a[n][m - 1] + a[n - 1][m - 1]
//ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><C7B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>֮<EFBFBD><D6AE><EFBFBD>ǵڶ<C7B5><DAB6><EFBFBD>Stirling<6E><67>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
//B(p + n) = B(n) + B(n + 1) (mod p)
//B(p^m + n) = m * B(n) + B(n + 1) (mod p)
//p<>Dz<EFBFBD><C7B2><EFBFBD><EFBFBD><EFBFBD>100<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>, <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Bell<6C><6C>ģС<C4A3><D0A1>100<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
//Bell<6C><6C>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ: N(p) = ((p^p) - 1) / (p - 1)
const int maxb = 105;
ll T[maxb], B[maxb];
void calBell() {
B[0] = B[1] = T[0] = 1;
for (int i = 2; i < maxb; i++) {
T[i - 1] = B[i - 1];
for (int j = i - 2; j >= 0; j--) { T[j] = (T[j] + T[j + 1]) % M; }
B[i] = T[0];
}
}
//<2F><><EFBFBD><EFBFBD>Bell(n)<29><>999999598 = 2 <20><> 13 <20><> 5281 <20><> 7283ȡģ O(P^2logP)
const int N = 7284, P = 999999598;
ll n; int p[5] = {2, 13, 5281, 7283}, B[2][N], T[N];
void init() {
T[0] = T[1] = B[0][0] = 1; B[0][1] = 2;
for (int i = 2, crt = 1; i < N; i++, crt ^= 1) {
T[i] = B[crt][0] = B[crt ^ 1][i - 1];
for (int j = 1; j <= i; j++) { B[crt][j] = (B[crt ^ 1][j - 1] + B[crt][j - 1]) % P; }
}
}
int b[N], c[N], d[70];
int cal(ll n, int mod) {
int len = 0;
for (int i = 0; i <= mod; i++) { b[i] = T[i] % mod; }
while (n) { d[len++] = n % mod; n /= mod; }
for (int i = 1; i < len; i++) {
for (int j = 1; j <= d[i]; j++) {
for (int k = 0; k < mod; k++) { c[k] = (b[k] * i + b[k + 1]) % mod; }
c[mod] = (c[0] + c[1]) % mod;
for (int k = 0; k <= mod; k++) { b[k] = c[k]; }
}
}
return c[d[0]];
}
ll bell(ll n) {
if (n < N) { return T[n]; }
ll t = 0;
for (int i = 0; p[i]; i++) {
t = (t + (P / p[i]) * powMod(P / p[i], p[i] - 2, p[i]) % P * cal(n, p[i]) % P) % P;
}
return t;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Catalan Number
//Cat(1) = 1, Cat(n) = (4n - 2) * Cat(n - 1) / (n + 1) = C(2n, n) / (n + 1) = C(2n, n) - C(2n, n - 1)
//<2F><>(0, 0)<29><><EFBFBD>ߵ<EFBFBD>(n, m)<29><><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD>ߵķ<DFB5><C4B7><EFBFBD><EFBFBD><EFBFBD>(x > y): C(n + m - 1, m) - C(n + m - 1, m - 1)
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD>ߵķ<DFB5><C4B7><EFBFBD><EFBFBD><EFBFBD>(x >= y): C(n + m, m) - C(n + m, m - 1)
//Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int a[105][105], b[105]; //<2F><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>
void Catalan() {
int i, j, len, carry, temp;
a[1][0] = b[1] = len = 1;
for (i = 2; i <= 100; i++) {
for (j = 0; j < len; j++) { //<2F>˷<EFBFBD>
a[i][j] = a[i - 1][j] * (4 * (i - 1) + 2);
}
carry = 0;
for (j = 0; j < len; j++) { //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><CBBD><EFBFBD>
temp = a[i][j] + carry;
a[i][j] = temp % 10;
carry = temp / 10;
}
while (carry) { //<2F><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
a[i][len++] = carry % 10;
carry /= 10;
}
carry = 0;
for (j = len - 1; j >= 0; j--) { //<2F><><EFBFBD><EFBFBD>
temp = carry * 10 + a[i][j];
a[i][j] = temp / (i + 1);
carry = temp % (i + 1);
}
while (!a[i][len - 1]) { len--; } //<2F><>λ<EFBFBD><EFBFBD><E3B4A6>
b[i] = len;
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void printCatalan(int n) {
for (int i = b[n] - 1; i >= 0; i--) { printf("%d", a[n][i]); }
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>ź<EFBFBD><C5BA>ӵķ<D3B5><C4B7><EFBFBD><EFBFBD><EFBFBD>
//k<><6B><EFBFBD><EFBFBD> m<><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>пպ<D0BF><D5BA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><>ͬ <20><>ͬ <20><> m^k
//<2F><>ͬ <20><>ͬ <20><> m!*Stirling2(k, m)
//<2F><>ͬ <20><>ͬ <20><> <20><>(m, i=1)Stirling2(k, i)
//<2F><>ͬ <20><>ͬ <20><> Stirling2(k, m)
//<2F><>ͬ <20><>ͬ <20><> C(m + k - 1, k)
//<2F><>ͬ <20><>ͬ <20><> C(k - 1, m - 1)
//<2F><>ͬ <20><>ͬ <20><> 1/(1-x)(1-x^2)...(1-x^m)<29><>x^k<><6B><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
//<2F><>ͬ <20><>ͬ <20><> x^m/(1-x)(1-x^2)...(1-x^m)<29><>x^k<><6B><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
//<2F><><EFBFBD>Ź<EFBFBD>ʽ
//D(1) = 0, D(2) = 1, D(n) = (n - 1)(D(n - 2) + D(n - 1))
//<2F><>չ Cayley <20><>ʽ
//<2F><><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD>, m<><6D><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>ͼ, <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>a[i]<5D><><EFBFBD><EFBFBD>, <20><>ô<EFBFBD><C3B4>s - 1<><31><EFBFBD>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD>Ϊn^(s-2)a[1]a[2]...a[m]