// Problem: U670613 warp // Contest: Luogu // URL: https://www.luogu.com.cn/problem/U670613 // Memory Limit: 512 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include // #include #define multiple_cases(T) signed T; cin >> T; while (T--) #define variable_name(x) #x #define all(x) (x).begin(), (x).end() #define adebug(a, b, c) #a << "[" << (b) << "..." << (c) << "] = " << vector::type>((a) + (b), (a) + (c) + 1) #define file_io(a) (freopen(#a ".in", "r", stdin), freopen(#a ".out", "w", stdout)) #ifdef assert #undef assert #endif #define assert(x) if (!(x)) { std::cerr << "Assertion failed: " << #x << ", line " << __LINE__ << std::endl; exit(1); } else; using namespace std; // using namespace __gnu_cxx; // using namespace __gnu_pbds; const int mod = 1000000007; template T quickpower(T a, Tb b) { if (b < 0) b = b % (mod - 1) + mod - 1; T c = 1; while (b) { if (b & 1) { c *= a; c %= mod; } a *= a; a %= mod; b >>= 1; } return c; } template T auto_quickpower(T a, Tb b) { T c = 1; while (b) { if (b & 1) { c *= a; } a *= a; b >>= 1; } return c; } namespace quick_io { template ostream& operator<<(ostream& os, const tuple& t); template ostream &operator<<(ostream &A, const vector &b); template ostream &operator<<(ostream &A, const deque &b); template ostream &operator<<(ostream &A, const pair &b); template ostream &operator<<(ostream &A, const set &b); template ostream &operator<<(ostream &A, const multiset &b); template ostream &operator<<(ostream &A, const map &b); template ostream &operator<<(ostream &A, const multimap &b); template ostream &operator<<(ostream &A, const unordered_set &b); template ostream &operator<<(ostream &A, const unordered_multiset &b); template ostream &operator<<(ostream &A, const unordered_map &b); template ostream &operator<<(ostream &A, const unordered_multimap &b); template ostream &operator<<(ostream &A, const vector &b) { A << "["; for (typename vector::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "]"; } template ostream &operator<<(ostream &A, const deque &b) { A << "["; for (typename deque::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "]"; } template ostream &operator<<(ostream &A, const pair &b) { return A << '(' << b.first << ',' << b.second << ')'; } template ostream &operator<<(ostream &A, const set &b) { A << "{"; for (typename set::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const multiset &b) { A << "{"; for (typename multiset::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const map &b) { A << "{"; for (typename map::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const multimap &b) { A << "{"; for (typename multimap::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const unordered_set &b) { A << "{"; for (typename unordered_set::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const unordered_multiset &b) { A << "{"; for (typename unordered_multiset::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const unordered_map &b) { A << "{"; for (typename unordered_map::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } template ostream &operator<<(ostream &A, const unordered_multimap &b) { A << "{"; for (typename unordered_multimap::const_iterator it = b.begin(); it != b.end(); ++it) { if (it != b.begin()) A << ","; A << *it; } return A << "}"; } void print_tuple(ostream&, const tuple<>&) {} template void print_tuple(ostream& os, const tuple& t) { os << get<0>(t); if (sizeof...(Rest) > 0) { os << ","; print_tuple(os, reinterpret_cast&>(t)); } } template ostream& operator<<(ostream& os, const tuple& t) { os << "("; print_tuple(os, t); return os << ")"; } template istream &operator>>(istream &A, pair &b) { return A >> b.first >> b.second; } template void print_array(T b, T e, string s = " ") { while (b != e) { cout << *b; b++; if (b != e) { cout << s; } } } template void auto_print(T &b, size_t n, string s = " ") { for (size_t i = 1; i < n; i++) { cout << b[i] << s; } cout << b[n]; } template void auto_print(T &b, string s = " ") { for (auto i : b) { cout << i << s; } } template void print_n(T b, size_t n, string s = " ") { if (n == 0) return; cout << *b; for (size_t i = 1; i < n; i++) { b++; cout << s << *b; } } template void read_array(T b, T e) { while (b != e) { cin >> *b; b++; } } template void auto_read(T &b, size_t n) { for (size_t i = 1; i <= n; i++) { cin >> b[i]; } } template void read_n(T b, size_t n) { cin >> *b; for (size_t i = 1; i < n; i++) { b++; cin >> *b; } } template std::string to_string(const T& value) { std::ostringstream oss; oss << value; return oss.str(); } std::string debug_index() { return ""; } template std::string debug_index(const first_t& first, const rest_t&... rest) { return "[" + to_string(first) + "]" + debug_index(rest...); } template auto get_value(T&& arr) -> decltype(std::forward(arr)) { return std::forward(arr); } template auto get_value(T&& arr, first_t&& first, rest_t&&... rest) { return get_value( std::forward(arr)[std::forward(first)], std::forward(rest)... ); } #define debug(first, ...) #first << debug_index(__VA_ARGS__) << " = " << get_value(first, ##__VA_ARGS__) #define spc << ' ' << #undef quick_io_int_length_limit #undef quick_io_int_radix_type #undef quick_io_length_type } using namespace quick_io; namespace MATH { template Ta quickpower(Ta a, Tb b, Tm MOD) { // MOD \in P if (b < 0) { b = b % (MOD - 1) + MOD - 1; } a %= MOD; Ta c = 1; while (b) { if (b & 1) { c *= a; c %= MOD; } a *= a; a %= MOD; b >>= 1; } return c; } template T gcd(T a, T b) { if (b == T(0)) return a; return gcd(b, a % b); } template T lcm(T a, T b) { return a * b / gcd(a, b); } template T exgcd(T a, T b, T1 &x, T2 &y) { if (b == 0) { x = 1; y = 0; return a; } T ans = exgcd(b, a % b, x, y); T1 X = y; T2 Y = (T2)x - ((T2)a / (T2)b) * y; x = X; y = Y; return ans; } int log2_(char k) { return 31 - __builtin_clz((unsigned int)k); } int log2_(unsigned char k) { return 31 - __builtin_clz((unsigned int)k); } int log2_(short k) { return 31 - __builtin_clz((unsigned int)k); } int log2_(unsigned short k) { return 31 - __builtin_clz((unsigned int)k); } int log2_(int k) { return 31 - __builtin_clz((unsigned int)k); } int log2_(unsigned int k) { return 31 - __builtin_clz((unsigned int)k); } int log2_(long long k) { return 63 - __builtin_clzll((unsigned long long)k); } int log2_(unsigned long long k) { return 63 - __builtin_clzll((unsigned long long)k); } template void build_power(T *power_array, T2 power_base, size_t len) { power_array[0] = 1; for (size_t i = 1; i <= len; i++) { power_array[i] = power_array[i - 1] * (T)power_base; } } template void build_factorial(int n, T1 *f, T2 *inv) { f[0] = 1; for (int i = 1; i <= n; i++) { f[i] = f[i - 1] * (T1)i; } if (inv == nullptr) { return; } inv[n] = T2(1) / T2(f[n]); for (int i = n - 1; i >= 0; i--) { inv[i] = inv[i + 1] * (T2)(i + 1); } } template T1 C(size_t n, size_t m, T1 *f, T2 *i) { if (m > n) return 0; return f[n] * (T1)i[m] * (T1)i[n - m]; } } namespace modulo_int { #define mint_int long long void exgcd(mint_int& x, mint_int& y, mint_int n, mint_int m) { if (m) { exgcd(y, x, m, n % m); y -= n / m * x; } else { x = 1; y = 0; } } mint_int mint_exgcd_a, mint_exgcd_b; #define mint_mod mod struct mint { mint_int n; mint() : n(0) {} mint(const mint_int &_n) { n = (_n % mint_mod + mint_mod) % mint_mod; } template const mint operator+(const T &x) const { return n + mint(x).n; } template const mint operator-(const T &x) const { return n - mint(x).n; } template const mint operator*(const T &x) const { return n * mint(x).n; } template const mint operator%(const T &x) const { return n % mint(x).n; } template const mint operator|(const T &x) const { return n | mint(x).n; } template const mint operator&(const T &x) const { return n & mint(x).n; } template const mint operator^(const T &x) const { return n ^ mint(x).n; } template const mint operator/(const T &x) const { exgcd(mint_exgcd_a, mint_exgcd_b, mint(x).n, mint_mod); return n * mint_exgcd_a; } template mint &operator+=(const T x) { return *this = *this + (mint)x; } template mint &operator-=(const T x) { return *this = *this - (mint)x; } template mint &operator*=(const T x) { return *this = *this * (mint)x; } template mint &operator/=(const T x) { return *this = *this / (mint)x; } template mint &operator%=(const T x) { return *this = *this % (mint)x; } template mint &operator|=(const T x) { return *this = *this | (mint)x; } template mint &operator&=(const T x) { return *this = *this & (mint)x; } template mint &operator^=(const T x) { return *this = *this ^ (mint)x; } mint &operator++() { return *this = n + 1; } mint &operator--() { return *this = n - 1; } mint operator++(signed) { n = ((n + 1 == mint_mod) ? 0 : (n + 1)); return n - 1; } mint operator--(signed) { n = (n ? (n - 1) : (mint_mod - 1)); return n + 1; } template bool operator<(const T &b) { return n < mint(b).n; } template bool operator<=(const T &b) { return n <= mint(b).n; } template bool operator>(const T &b) { return n > mint(b).n; } template bool operator>=(const T &b) { return n >= mint(b).n; } template bool operator==(const T &b) { return n == mint(b).n; } template bool operator!=(const T &b) { return n != mint(b).n; } operator mint_int() const { return n; } mint operator-() const { return -n; } const mint &operator+() const { return *this; } }; istream &operator>>(istream &A, mint &b) { mint_int c; A >> c; b = c; return A; } ostream &operator<<(ostream &A, const mint &b) { return A << b.n; } #undef mint_mod #undef mint_int } #define int long long #if 1 using ll = long long; using ull = unsigned long long; using i8 = int8_t; using u8 = uint8_t; using i16 = int16_t; using u16 = uint16_t; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; using i128 = __int128_t; using u128 = __uint128_t; using pii = pair; using vi = vector; using vvi = vector; using vpii = vector; using sti = set; using mpii = map; using usti = unordered_set; using umpii = unordered_map; using msti = multiset; using umsti = unordered_multiset; using sos = ostream; using sis = istream; using soss = ostringstream; using siss = istringstream; #endif #define min(x,y) ((x) < (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y)) #define lowbit(x) ((x) & -(x)) #define abs(x) ((x) < 0 ? -(x) : (x)) // #define swap(a,b) a ^= b ^= a ^= b #define INF 1e18 #define bin(a,b) bitset(b) #define getbit(a,b) (((a) >> (b)) & 1) ostream &cans(cout); // #define cout cerr using namespace MATH; using modulo_int::mint; // using namespace graph_algorithm; // using namespace my_random; // using fast_ios::ewin; // using fast_ios::ewout; // #define cin ewin // #define cout ewout int p, q, r, s; mint a[3000005], fac[3000005], inv[3000005]; #define C(n, m) C(n, m, fac, inv) signed main() { build_factorial(3000000, fac, inv); cin >> p >> q >> r; if (!(p + q + r)) { cout << 1; return 0; } s = p + q + r; for (int i = 0; i <= s + 1; i++) { a[i] = C(s + 1, i); if ((s + 1 - i) & 1) { a[i] = -a[i]; } } a[0]--; // cout << adebug(a, 0, s) << endl; for (int i = 0; i <= s; i++) { a[i] = a[i] / -2; a[i + 1] -= a[i]; } // cout << adebug(a, 0, s) << endl; mint ans = 0; for (int i = 0; i <= s; i++) { ans += a[i] * C(p + i - 1, i - 1) * C(q + i - 1, i - 1) * C(r + i - 1, i - 1); } cout << ans << endl; return 0; }