# SYSU-10，URAL 1675，容斥原理

ans = C（m,0）* (2^m-1)^n - C（m,1）* (2^(m-1)-1)^n + C（m,2）* (2^(m-2)-1)^n ............

（我是无法理解为何是容斥原理，形式很像，各种直觉上来说也是，但是我没办法把他化成集合与的加加减减这种形式）

 1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 #include <algorithm>
5 #include <cmath>
6
7 using namespace std;
8
9 #define MAXN 111111
10 #define LL long long
11
12 const LL MOD = 1e9 + 7;
13
14 LL poww[MAXN], inv[MAXN];
15
16 int n, m, k, l;
17
18 LL quick_pow(LL a, LL b) {
19     LL res = 1, base = a;
20     while (b > 0) {
21         if (b&1) res = (res * base) % MOD;
22         base = (base * base ) % MOD;
23         b >>= 1;
24     }
25     return res;
26 }
27
28 void pre() {
29     poww[0] = 1;
30     inv[0] = 1;
31     for (int i = 1; i < MAXN; ++i) {
32         poww[i] = poww[i-1] * i % MOD;
33         inv[i] = quick_pow(poww[i], MOD - 2);
34     }
35 }
36
37 #define C(n,m) ((m)>(n)?0:(poww[n]*inv[m]%MOD)*inv[n-m]%MOD)
38
39 LL calc(int n, int m) {
40     LL res = 0;
41     for (int i = m, k = 1; i >= 0; --i, k = -k) {
42         res += (MOD + k * (C(m, i) * quick_pow(quick_pow(2, i) - 1, n)));
43         res %= MOD;
44     }
45     return res;
46 }
47
48 int main() {
49     pre();
50     while (scanf("%d%d%d%d", &n, &m, &k, &l) == 4) {
51         LL ans = (C(n, k) * C(m, l) % MOD * calc(n - k, m - l) % MOD) + MOD;
52         cout << ans % MOD << endl;
53     }
54     return 0;
55 }
URAL 1675

posted @ 2016-08-11 10:31  F.D.His.D  阅读(...)  评论(...编辑  收藏