#include #include using namespace std; using namespace atcoder; using ll = long long; #define endl '\n' struct S{ ll tot; ll add; }; S op(S l, S r){ return S{l.tot + r.tot, l.add + r.add}; } S e(){ return {0, 0}; } using F = ll; S mapping(F x, S y){ return S{y.tot + x * y.add, y.add}; } F composition(F l, F r){ return l + r; } F id(){ return 0LL; } void solve(){ int n0, n1, n2, m; cin >> n0 >> n1 >> n2 >> m; int n = n0 + n1 + n2; vector N = {n0, n1, n2}; vector> imos(3, vector()); vector> dub(3, vector()); for(int i = 0; i < 3; i++){ imos[i].assign(N[i] + 2, 0); dub[i].assign(N[i] + 2, false); } auto f=[&](int x) -> pair { if(x <= n0) return {0, x}; else if(x <= n0 + n1) return {1, x - n0}; else if(x <= n) return {2, x - n0 - n1}; else return {3, x - n - 1}; }; vector>>> E(3, vector>>(3, vector>())); int u, v; for(int i = 0; i < m; i++){ cin >> u >> v; auto f1 = f(u); auto f2 = f(v); if(f1.first == f2.first){ if(f1.first == 3){ cout << 0 << endl; return; } if(f1.second > f2.second) swap(f1, f2); if(f1.second + 1 == f2.second) dub[f1.first][f1.second] = true; imos[f1.first][f1.second]++; imos[f1.first][f2.second]--; } else{ if(f1.first > f2.first) swap(f1, f2); if(f2.first == 3){ f2.first = f1.first; if(f2.second == 1) f2.second = N[f1.first] + 1; if(f1.second > f2.second) swap(f1, f2); if(f1.second + 1 == f2.second) dub[f1.first][f1.second] = true; imos[f1.first][f1.second]++; imos[f1.first][f2.second]--; } else{ E[f1.first][f2.first].push_back({f1.second, f2.second}); E[f2.first][f1.first].push_back({f2.second, f1.second}); } } } vector> B(3, vector()); for(int i = 0; i < 3; i++){ for(int j = 0; j < N[i] + 1; j++){ if(imos[i][j] == 0 && !dub[i][j]) B[i].push_back(j); imos[i][j + 1] += imos[i][j]; } } auto LR=[&](int i, int j)-> pair, vector> { vector L(N[i] + 2, 0), R(N[i] + 2, N[j] + 1), ret(N[i] + 1); for(auto tmp:E[i][j]){ int p1 = tmp.first; int p2 = tmp.second; L[p1] = max(L[p1], p2); R[p1] = min(R[p1], p2); } for(int k = 1; k < N[i] + 2; k++) L[k] = max(L[k], L[k - 1]); for(int k = N[i]; k >= 0; k--) R[k] = min(R[k], R[k + 1]); return {L, R}; /* for(int k = 0; k < N[i] + 1; k++){ auto itl = lower_bound(B[j].begin(), B[j].end(), L[k]); auto itr = lower_bound(B[j].begin(), B[j].end(), R[k + 1]); ret[k] = max(0, int(itr - itl)); } return ret; */ }; auto ok=[&](int i, int j){ return (imos[i][j] == 0) && (!dub[i][j]); }; auto tmp1 = LR(0, 1); auto tmp2 = LR(0, 2); vector, pair>> Q; for(int k = 0; k < N[0] + 1; k++){ if(ok(0, k) && tmp1.first[k] < tmp1.second[k + 1] && tmp2.first[k] < tmp2.second[k + 1]){ Q.push_back({{tmp1.first[k], tmp1.second[k + 1]}, {tmp2.first[k], tmp2.second[k + 1]}}); } } vector init(N[2] + 1); for(int i = 0; i < N[2] + 1; i++){ init[i] = {0, 0}; if(ok(2, i)) init[i].add = 1; } lazy_segtree seg(init); auto tmp3 = LR(1, 2); ll ans = 0; vector>> add(N[1] + 1, vector>()); vector>> sub(N[1] + 1, vector>()); for(auto tmp:Q){ add[tmp.first.second - 1].push_back(tmp.second); sub[tmp.first.first].push_back(tmp.second); } for(int i = 0; i < N[1] + 1; i++){ for(auto tmp:sub[i]){ // cout << "S" << " " << tmp.first << " " << tmp.second << endl; ans -= seg.prod(tmp.first, tmp.second).tot; } if(ok(1, i)){ if(tmp3.first[i] < tmp3.second[i + 1]){ seg.apply(tmp3.first[i], tmp3.second[i + 1], 1); } } for(auto tmp:add[i]){ // cout << "A" << " " << tmp.first << " " << tmp.second << endl; ans += seg.prod(tmp.first, tmp.second).tot; } } cout << ans << endl; /* ll cnt = 0; auto tmp3 = LR(1, 2); for(auto tmp:Q){ auto p1 = tmp.first; auto p2 = tmp.second; for(int i = p1.first; i < p1.second ; i++){ if(!ok(1, i)) continue; for(int j = p2.first; j < p2.second; j++){ if(ok(2, j) && tmp3.first[i] <= j && j < tmp3.second[i + 1]) cnt++; } } } cout << cnt << endl; */ /* auto f1=[&](int i, int j){ auto R = LR(i, j); ll ret = 0; for(int k = 0; k < N[i] + 1; k++){ if(imos[i][k] == 0 && !dub[i][k]){ ret += R[k]; } } return ret; }; auto f2=[&](int i){ auto R1 = LR(i, (i + 1) % 3); auto R2 = LR(i, (i + 2) % 3); ll ret = 0; for(int k = 0; k < N[i] + 1; k++){ if(imos[i][k] == 0 && !dub[i][k]){ ret += ll(R1[k]) * ll(R2[k]); } } return ret; }; ll ans = ll(B[0].size()) * ll(B[1].size()) * ll(B[2].size()); for(int i = 0; i < 3; i++){ // cout << ans << endl; ans -= ll(B[i].size()) * f1((i + 1) % 3, (i + 2) % 3); // cout << ans << endl; ans += f2(i); } cout << ans << endl; */ /* ll cnt = 0; for(auto i:B[0]){ for(auto j:B[1]){ for(auto k:B[2]){ vector A = {i, j, k}; bool ok = true; for(int t1 = 0; t1 < 2; t1++){ for(int t2 = t1 + 1; t2 < 3; t2++){ for(auto tmp:E[t1][t2]){ int p1 = tmp.first; int p2 = tmp.second; if(bool(A[t1] < p1) ^ (A[t2] < p2)) ok = false; } } } if(ok) cnt++; } } } cout << cnt << endl; */ } int main(){ cin.tie(0)->sync_with_stdio(0); solve(); }