1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
#include <bits/stdc++.h>
inline char read() { static const int IN_LEN = 1000000; static char buf[IN_LEN], *s, *t; if (s == t) { t = (s = buf) + fread(buf, 1, IN_LEN, stdin); if (s == t) return -1; } return *s++; }
template<class T> inline void read(T &x) { static bool iosig; static char c; for (iosig = false, c = read(); !isdigit(c); c = read()) { if (c == '-') iosig = true; if (c == -1) return; } for (x = 0; isdigit(c); c = read()) x = (x + (x << 2) << 1) + (c ^ '0'); if (iosig) x = -x; }
const int OUT_LEN = 1000000; char obuf[OUT_LEN], *oh = obuf;
inline void print(char c) { if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf; *oh++ = c; }
template<class T> inline void print(T x) { static int buf[30], cnt; if (x == 0) { print('0'); } else { if (x < 0) print('-'), x = -x; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; while (cnt) print((char)buf[cnt--]); } }
inline void flush() { fwrite(obuf, 1, oh - obuf, stdout); }
const int MAXN = 2005; const int MOD = 1e9 + 7;
#define long long long typedef unsigned int uint;
int C[MAXN][MAXN], p[MAXN], s1[MAXN], s2[MAXN];
inline uint getC(int x, int y) { return y < 0 ? x < 0 : C[x][y]; }
inline uint calc(int a, int b, int cnt) { if (a < b) std::swap(a, b); long ret = 0; for (register int i = a - b, r = std::min(a, cnt), j, k; i <= r; i++) { j = i - a + b, k = cnt - i - j; if (j >= 0 && j <= b && k >= 0 && a - i - k >= 0) (ret += (long)C[cnt][i] * C[cnt - i][j] % MOD * (long)p[k] % MOD * getC(a - i - k + cnt - 1, cnt - 1)) %= MOD; } return ret; }
int main() { #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); #endif register int n1, n2, n3, n4; read(n1), read(n2), read(n3), read(n4); p[0] = C[0][0] = 1; register int max = std::max(n1 + n2, n3 + n4) + 1; for (register int i = 1; i < max; i++) p[i] = ((long)p[i - 1] << 1) % MOD; for (register int i = 1; i < max; i++) C[i][0] = 1; for (register int i = 1; i < max; i++) for (register int j = 1; j <= i; j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
for (register int i = 0, r = n1 + n2; i <= r; i++) s1[i + 1] = calc(n1, n2, i); for (register int i = 0, r = n3 + n4; i <= r; i++) s2[i + 1] = calc(n3, n4, i); register long ans = 0; for (register int i = 1, r = n1 + n2 + 1; i <= r; i++) (ans += (long)s1[i] * (s2[i - 1] + (long)2 * s2[i] + s2[i + 1])) %= MOD; print(ans); flush(); }
|