Problem:
Union of Rectangles
Given a set of $N$ axis-aligned rectangles in the plane, find the area of regions which are covered by at least one rectangle.
Input
The input is given in the following format.
$N$
$x1_1$ $y1_1$ $x2_1$ $y2_1$
$x1_2$ $y1_2$ $x2_2$ $y2_2$
:
$x1_N$ $y1_N$ $x2_N$ $y2_N$
($x1_i, y1_i$) and ($x2_i, y2_i$) are the coordinates of the top-left corner and the bottom-right corner of the $i$-th rectangle respectively.
Constraints
$ 1 \leq N \leq 2000 $
$ −10^9 \leq x1_i < x2_i\leq 10^9 $
$ −10^9 \leq y1_i < y2_i\leq 10^9 $
Output
Print the area of the regions.
Sample Input 1
2
0 0 3 4
1 2 4 3
Sample Output 1
13
Sample Input 2
3
1 1 2 5
2 1 5 2
1 2 2 5
Sample Output 2
7
Sample Input 3
4
0 0 3 1
0 0 1 3
0 2 3 3
2 0 3 3
Sample Output 3
8

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; ++i)

int main() {
    int N;
    cin >> N;
    vector<int> X1, X2, Y1, Y2, X, Y;
    rep(i, N) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        X1.push_back(x1);
        X2.push_back(x2);
        Y1.push_back(y1);
        Y2.push_back(y2);
        X.push_back(x1);
        X.push_back(x2);
        Y.push_back(y1);
        Y.push_back(y2);
    }

    // 座標圧縮
    auto X_uni = X, Y_uni = Y;
    sort(X_uni.begin(), X_uni.end());
    sort(Y_uni.begin(), Y_uni.end());
    X_uni.erase(unique(X_uni.begin(), X_uni.end()), X_uni.end());
    Y_uni.erase(unique(Y_uni.begin(), Y_uni.end()), Y_uni.end());

    vector<int> X1_id(N), X2_id(N), Y1_id(N), Y2_id(N);
    rep(i, N) {
        auto id_x1 = lower_bound(X_uni.begin(), X_uni.end(), X1[i]);
        auto id_x2 = lower_bound(X_uni.begin(), X_uni.end(), X2[i]);
        auto id_y1 = lower_bound(Y_uni.begin(), Y_uni.end(), Y1[i]);
        auto id_y2 = lower_bound(Y_uni.begin(), Y_uni.end(), Y2[i]);
        X1_id[i] = id_x1 - X_uni.begin();
        X2_id[i] = id_x2 - X_uni.begin();
        Y1_id[i] = id_y1 - Y_uni.begin();
        Y2_id[i] = id_y2 - Y_uni.begin();
    }

    int R = X_uni.size(), C = Y_uni.size();
    // imos法で埋めていく
    vector<vector<int>> S(R, vector<int>(C, 0));
    rep(i, N) {
        int x1 = X1_id[i], x2 = X2_id[i], y1 = Y1_id[i], y2 = Y2_id[i];
        S[x1][y1]++;
        S[x1][y2]--;
        S[x2][y1]--;
        S[x2][y2]++;
    }

    rep(i, R) rep(j, C - 1) S[i][j + 1] += S[i][j];
    rep(i, R - 1) rep(j, C) S[i + 1][j] += S[i][j];

    ll res = 0;
    rep(i, R - 1) {
        rep(j, C - 1) {
            ll cur_area =
                (ll)(X_uni[i + 1] - X_uni[i]) * (Y_uni[j + 1] - Y_uni[j]);
            if (S[i][j]) res += cur_area;
        }
    }

    cout << res << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 65844
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vd = vector<double>;
using vvd = vector<vector<double>>;
using vstr = vector<string>;
using vchar = vector<char>;
using vvchar = vector<vector<char>>;
using vb = vector<bool>;
using vvb = vector<vector<bool>>;
using vvvb = vector<vector<vector<bool>>>;
using pii = pair<int,int>;
using pll = pair<long long, long long>;
using Graph = vector<vector<int>>;
using WeightedGraph = vector<vector<pair<int,ll>>>;
const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
const int dy[8] = {0, 1, 0, -1, 1, -1, 1, -1};

#define rep(i, a, b) for(ll i = (ll)a; i < (ll)b; i++)
#define REP(i, a, b) for (ll i = (ll)a; i <= (ll)b; i++)
#define rrep(i, a, b) for(ll i = (ll)b-1; i >= (ll)a; i--)
#define RREP(i, a, b) for(ll i = (ll)b; i >= (ll)a; i--)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define YESNO(flag) cout << (flag ? "Yes" : "No") << "\n"
#define spa " "
#define mint modint<MOD>

const int inf = 1070000000;
const long long INF = 4500000000000000000;
//const long long MOD = 998244353;
const long long MOD = 1000000007;
const double pi = 3.141592653589793238;
const double eps = (1e-10);
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

template<typename T> 
inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<typename T> 
inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template<typename S, typename T> 
pair<S, T> operator+(pair<S, T> a, pair<S, T> b) {
    pair<S, T> ans;
    ans.first = a.first + b.first;
    ans.second = a.second + b.second;
    return ans;
} 
template<typename T> 
vector<T> operator+(vector<T> a, vector<T> b) {
    int N = max(a.size(), b.size());
    vector<T> c(N);
    for(int i = 0; i < N; i++) {
        if(i >= a.size()) c[i] = b[i];
        else if(i >= b.size()) c[i] = a[i];
        else c[i] = a[i] + b[i];
    }
    return c;
}
template<typename T> 
vector<T> operator*(vector<T> a, vector<T> b) {
    int N = max(a.size(), b.size()), n = min(a.size(), b.size());
    vector<T> c(N, 0);
    for(int i = 0; i < n; i++) {
        c[i] = a[i] * b[i];
    }
    return c;
}

//拡張ユークリッド
ll ext_gcd(ll a, ll b, ll &x, ll &y) {
    if(b == 0) {
        x = 1, y = 0;
        return a;
    }

    ll q = a/b;
    ll g = ext_gcd(b, a-q*b, x, y);
    ll z = x-q*y;
    x = y, y = z;
    return g;
}
//mod mにおけるaの逆元. aとmは互いに素.
ll inverse(ll a, ll m) {
    ll x, y;
    ext_gcd(a, m, x, y);
    x = (x+m) % m;
    return x;
}
//modint
template<std::uint_fast64_t mod> 
struct modint {
    using u64 = std::uint_fast64_t;
    u64 val;

    modint(u64 v = 0) : val(v % mod) {}

    bool operator==(modint other) {
        return val == other.val;
    }
    bool operator<(const modint& other) const {
        return val < other.val;
    }
    // operator> (大なり)
    bool operator>(const modint& other) const {
        return val > other.val;
    }
    modint operator+(modint other) {
        modint<mod> ans;
        ans.val = val + other.val;
        if(ans.val >= mod) ans.val -= mod;
        return ans;
    }
    modint operator-(modint other) {
        modint<mod> ans;
        if(val < other.val) val += mod;
        ans.val = val - other.val;
        return ans;
    }
    modint operator*(modint other) {
        modint<mod> ans;
        ans.val = (val * other.val) % mod;
        return ans;
    }
    modint operator/(modint other) {
        modint<mod> ans;
        ans.val = (val * inverse(other.val, mod)) % mod;
        return ans;
    }
    modint &operator+=(modint other) {
        *this = *this + other;
        return *this;
    }
    modint &operator-=(modint other) {
        *this = *this - other;
        return *this;
    }
    modint &operator*=(modint other) {
        *this = *this * other;
        return *this;
    }
    modint &operator/=(modint other) {
        *this = *this / other;
        return *this;
    }
    modint &operator++() {
        *this += 1;
        return *this;
    }
    modint &operator++(int) {
        ++(*this);
        return *this;
    }
    modint &operator--() {
        *this -= 1;
        return *this;
    }
    modint &operator--(int) {
        --(*this);
        return *this;
    }
};
//modintの入出力
template<std::uint_fast64_t mod> 
std::ostream& operator<<(std::ostream &os, const modint<mod> &x) {
    // modint の 'val' メンバを出力ストリーム(os)に渡す
    os << x.val;
    return os; // ストリームを返す (チェーンのため)
}
template<std::uint_fast64_t mod> 
std::istream& operator>>(std::istream& is, modint<mod> &x) {
    // modintが内部で使っているu64型を取得
    using u64 = typename modint<mod>::u64; 
    
    u64 input_value;
    is >> input_value; // (1) istream(cin) から一時変数に値を読み込む
    
    // (2) 読み込んだ値を使って modint を再構築する
    //     modintのコンストラクタが (input_value % mod) を処理してくれる
    x = modint<mod>(input_value); 
    
    return is; // (3) ストリームを返す (チェーンのため)
}
//累乗, x^n
template<typename T> 
T pow(T x, int n) {
    T ans = 1;
    while(n > 0) {
        if(n & 1) ans *= x;
        x *= x;
        n >>= 1; 
    }
    return ans;
}
//階乗, n!
template<typename T> 
T fact(T n) {
    if(n == 0) return 1;
    return n * fact(n-1);
}
//nPk
template<typename T> 
T perm(T n, T k) {
    if(k == 0) return 1;
    return n * perm(n-1, k-1);
}
//nCk
template<typename T> 
T comb(T n, T k) {
    if(k > n) return 0;
    return perm(n, min(k, n-k))/fact(min(k, n-k));
}
//ord(n)
ll ord(ll n, ll p) {
    int ans = 0;
    while(n % p == 0) {
        n /= p;
        ans++;
    }
    return ans;
}
//ルジャンドルの公式ord(n!)
ll factord(ll n, ll p) {
    ll ans = 0;
    ll q = p, tmp = n;
    while(tmp > 0) {
        tmp = n/q;
        ans += tmp;
        q *= p;
    }
    return ans;
}
//素因数分解, O(√N)
vector<pair<ll,ll>> factorize(ll N) {
    vector<pair<ll,ll>> ans;
    for(ll p = 2; p*p <= N; p++) {
        int ex = 0;
        while(N % p == 0) {
            N /= p;
            ex++;
        }
        if(ex != 0) ans.push_back({p,ex});
    }
    if(N != 1) ans.push_back({N,1});
    return ans;
}
//素数判定
bool isprime(long long x) {
    if(x == 1) return false;
    
    for(long long i = 2; i*i <= x; i++) {
        if(x % i == 0) return false;
    }
    return true;
}
//エラトステネスの篩
struct Eratosthenes {
    vector<bool> prime;
    vector<int> minfactor;
    vector<int> mobius;
    vector<ll> euler;

    //コンストラクタ O(NloglogN)
    Eratosthenes(int N) : prime(N+1, true),
                          minfactor(N+1, -1),
                          mobius(N+1, 1),
                          euler(N+1, 1) {
        prime[0] = false;
        prime[1] = false;
        minfactor[1] = 1;
        REP(i,1,N) euler[i] = i;

        for(int p = 2; p <= N; p++) {
            if(!prime[p]) continue;

            minfactor[p] = p;
            mobius[p] = -1;
            euler[p] = p-1;

            for(int q = 2; p*q <= N; q++) {
                prime[p*q] = false;
                if(minfactor[p*q] == -1) minfactor[p*q] = p;
                if(q % p == 0) mobius[p*q] = 0;
                else mobius[p*q] *= -1;
                euler[p*q] = euler[p*q]*(p-1)/p;
            }
        }
    }

    //素因数分解 O(logn)
    vector<pair<int,int>> factorize(int n) {
        vector<pair<int,int>> ans;
        while(n > 1) {
            int p = minfactor[n], exp = 0;
            while(n % p == 0) {
                n /= p;
                exp++;
            }
            ans.push_back({p, exp});
        }
        return ans;
    }
    //約数列挙 O(σ(n))
    vector<int> divisors(int n) {
        vector<int> ans = {1};
        while(n > 1) {
            int p = minfactor[n], d = 1, s = ans.size();
            while(n % p == 0) {
                d *= p;
                for(int i = 0; i < s; i++) {
                    ans.push_back(ans[i]*d);
                }
                n /= p;
            }
        }
        return ans;
    }
    //素数関数 O(n)
    int count(int n) {
        int ans = 0;
        REP(i,2,n) if(prime[i]) ans++;
        return ans;
    }
};
//高速ゼータ変換
template<typename T> 
void fast_zeta(vector<T> &f) {
    int N = f.size()-1;
    Eratosthenes sieve(N);
    for(int p = 2; p < N; p++) {
        if(!sieve.prime[p]) continue;
        
        for(int k = N/p; k >= 1; k--) {
            f[k] += f[k*p];
        }
    }
}
//高速メビウス変換
template<typename T> 
void fast_mobius(vector<T> &F) {
    int N = F.size()-1;
    Eratosthenes sieve(N);
    for(int p = 2; p < N; p++) {
        if(!sieve.prime[p]) continue;

        for(int k = 1; k*p <= N; k++) {
            F[k] -= F[k*p];
        }
    }
}
//添字GCD畳み込み
template<typename T> 
vector<T> gcd_conv(vector<T> &f, vector<T> &g) {
    int N = max(f.size(), g.size());
    vector<T> F(N, 0), G(N, 0), H(N);
    for(int i = 0; i < f.size(); i++) F[i] = f[i];
    for(int i = 0; i < g.size(); i++) G[i] = g[i];
    fast_zeta(F);
    fast_zeta(G);
    
    for(int i = 0; i < N; i++) H[i] = F[i]*G[i];
    fast_mobius(H);
    
    return H;
}

//行列積
template<typename T> 
vector<vector<T>> matrix_product(vector<vector<T>> A, vector<vector<T>> B) {
    int H = A.size(), W = A[0].size(), P = B.size(), Q = B[0].size();
    if(W != P) {
        cout << "matrix_size_error" << "\n";
        return vector<vector<T>>(0);
    }

    vector<vector<T>> C(H, vector<T>(Q, 0));
    rep(i,0,H) rep(j,0,Q) {
        rep(k,0,W) {
            C[i][j] += A[i][k]*B[k][j];
        }
    }
    return C;
}
//行列累乗
template<typename T> 
vector<vector<T>> matrix_pow(vector<vector<T>> A, ll n) {
    int N = A.size();
    vector<vector<T>> ans(N, vector<T>(N, 0));
    rep(i,0,N) ans[i][i] = 1;
    
    while(n > 0) {
        if(n & 1) ans = matrix_product(ans, A);
        A = matrix_product(A, A);
        n >>= 1; 
    }
    return ans;
}

//1+2+...+n = n(n+1)/2
ll tri(ll n) {
    ll x = n*(n+1);
    return x/2;
}

//座標圧縮
template<typename T> 
vector<T> compress(vector<T> &A) {
    vector<T> vals = A;
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

    for(int i = 0; i < (int)A.size(); i++) {
        A[i] = lower_bound(vals.begin(), vals.end(), A[i]) - vals.begin();
    }
    return vals;
}
template<typename T>
vector<T> compress2(vector<T> &A1, vector<T> &A2) {
    vector<T> vals;
    int N = A1.size();
    for(int i = 0; i < N; i++) {
        for(T d = 0; d <= 1; d++) {
            T a1 = A1[i] + d;
            T a2 = A2[i] + d;
            vals.push_back(a1);
            vals.push_back(a2);
        }
    }
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    
    for(int i = 0; i < N;  i++) {
        A1[i] = lower_bound(vals.begin(), vals.end(), A1[i]) - vals.begin();
        A2[i] = lower_bound(vals.begin(), vals.end(), A2[i]) - vals.begin();
    }
    return vals;
}

//正方形グリッドの右回転, 左回転
void rotate_right(vector<vector<char>> &S) {
    int N = S.size();
    auto T = S;
    rep(i,0,N) rep(j,0,N) {
        T[i][j] = S[N-1-j][i];
    }
    S = T;
}
void rotate_left(vector<vector<char>> &S) {
    int N = S.size();
    auto T = S;
    rep(i,0,N) rep(j,0,N) {
        T[i][j] = S[j][N-1-i];
    }
    S = T;
}

//2点(a,b)と(x,y)の距離
long double dist(pair<long double, long double> a, pair<long double, long double> b) {
    return sqrt((a.first-b.first)*(a.first-b.first) + (a.second-b.second)*(a.second-b.second));
}
long double man(pair<long double, long double> a, pair<long double, long double> b) {
    return abs(a.first-b.first) + abs(a.second-b.second);
}
//内分点
pair<long double, long double> internal_division(pair<long double, long double> a, pair<long double, long double> b, long double p) {
    long double x = a.first + (b.first - a.first) * p;
    long double y = a.second + (b.second - a.second) * p;
    return {x, y};
}

//桁数
int digit(ll N) {
    if(N <= 9) return 1;

    return 1 + digit(N / 10);
}
//A進数文字列NをB進数に変換. A,Bは10以下
string base_change(string N, ll A, ll B) {
    ll X = stoll(N), Y = 0;

    ll i = 1;
    while(X != 0) {
        Y += (X % 10) * i;
        i *= A;
        X /= 10;
    }

    X = Y, Y = 0;
    i = 1;
    while(X != 0) {
        Y += (X % B) * i;
        i *= 10;
        X /= B;
    }

    return to_string(Y);
}
//回文判定
bool palin(string S) {
    rep(i,0,S.size()) {
        if(S[i] != S[S.size()-1-i]) return false;
    }
    return true;
}

//hh:mm:ss to second
int convert_to_time(string S) {
    ll h = 10*(S[0]-'0') + (S[1]-'0');
    ll m = 10*(S[3]-'0') + (S[4]-'0');
    ll s = 10*(S[6]-'0') + (S[7]-'0');
    
    return h*3600+m*60+s;
}

//DFS
void dfs(const Graph &G, int v, vector<bool> &seen) { 
    seen[v] = true;
    
    for (auto next_v : G[v]) { 
        if (!seen[next_v]) {
            dfs(G, next_v, seen);
        }
    }
}
void griddfs(const vector<vector<char>> &G, int x, int y, vector<vector<bool>> &seen) {
    int H = G.size(), W = G[0].size();
    seen[x][y] = true;
    
    for (int i = 0; i < 8; i++) { 
        int nx = x + dx[i], ny = y + dy[i];
        if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
        if (!seen[nx][ny] and G[nx][ny] != '#') griddfs(G, nx, ny, seen);
    }
}
//BFS
void bfs(const Graph &G, int v, vector<int> &dist) {
    rep(i,0,dist.size()) dist[i] = inf;
    dist[v] = 0;
    queue<int> q;
    q.push(v);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(auto next_u : G[u]) {
            if(dist[next_u] == inf) {
                dist[next_u] = dist[u] + 1;
                q.push(next_u);
            }
        }
    }
}
void gridbfs(const vector<vector<char>> &G, int x, int y, vector<vector<int>> &dist) {
    int H = G.size(), W = G[0].size();
    dist[x][y] = 0;
    queue<pair<int, int>> q;
    q.push(make_pair(x, y));
    while(!q.empty()) {
        int x = q.front().first, y = q.front().second;
        q.pop();
        for(int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
            if(dist[nx][ny] == inf and G[nx][ny] != '#') {
                dist[nx][ny] = dist[x][y] + 1;
                q.push(make_pair(nx, ny));
            }
        }
    }
}
//ワーシャル・フロイド
vector<vector<ll>> floyd(vector<vector<ll>> G) {
    int N = G.size();
    auto dp = G;
    for (int k = 0; k < N; k++){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if(dp[i][j] > dp[i][k] + dp[k][j] and dp[i][k] != INF and dp[k][j] != INF) {
                    dp[i][j] = dp[i][k] + dp[k][j];
                }
            }
        }
    }
    return dp;
}
//サイクルがあるか判定
bool cycle(const Graph &G, int v, vector<bool> &seen,  vector<bool> &finished) {
    seen[v] = true;    // 行きがけ時に true になる
    for (auto v2 : G[v]) {
        //if (v2 が逆戻りの場合) continue;  // 無向グラフの場合は必要

        // 頂点 v2 がすでに探索済みの場合はスキップ 
        if (finished[v2]) continue;

        // サイクル検出
        if (seen[v2] && !finished[v2]) return true;

        // 頂点 v2 を再帰的に探索
        if (cycle(G, v2, seen, finished)) return true;
    }
    finished[v] = true;  // 帰りがけ時に true になる
    return false;
}

//Union-Find
struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
    vector<ll> cnt;
    
    UnionFind(int N) : par(N),
                       cnt(N, 1) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }
    
    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }
    
    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        cnt[ry] += cnt[rx];
    }
    
    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

    ll num(int x) { //データxと同じ木に属するデータの数を得る
        return cnt[x] = cnt[root(x)];
    }
};
//最小全域木
ll Kruskal(const WeightedGraph &G) {
    int N = G.size();
    return 0;
}
//BIT
struct BIT {
    vector<long long> array;
    const int n;

    BIT(int _n) : array(_n, 0), n(_n) {}

    //a_0 + ... + a_i
    long long sum(int i) {
        long long s = 0;
        while(i >= 0) {
            s += array[i];
            i -= (i+1) & -(i+1);
        }
        return s;
    }
    //a_i + ... + a_j
    long long sum(int i, int j) {
        long long ans_i = sum(i-1);
        long long ans_j = sum(j);
        return ans_j - ans_i;
    }
    //a_i += x
    void add(int i, long long x) {
        while(i < n) {
            array[i] += x;
            i += (i+1) & -(i+1);
        }
    }
};
//セグ木
struct SegTree {
    int n, sz;
    vector<long long> node;
    function<ll(ll, ll)> op = [](ll a, ll b) {return max(a,b);}; //セグ木上の積
    ll e = 0; //セグ木上の積の単位元

    SegTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        node.resize(2*n-1, e);
    }
    SegTree(vector<long long> a) {
        sz = a.size();

        n = 1;
        while(n < sz) n *= 2;
        node.resize(2*n-1, e);
        for(int i = 0; i < sz; i++) node[n-1+i] = a[i];
        for(int i = n-2; i >= 0; i--) node[i] = op(node[2*i+1], node[2*i+2]);
    }

    //a_iを取得
    long long get(int i) {
        return node[n-1+i];
    }
    //[a,b)における積
    long long prod(int a, int b, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;
        if(r <= a or b <= l) return e;
        if(a <= l and r <= b) return node[k];
        long long vl = prod(a, b, 2*k+1, l, (l+r)/2);
        long long vr = prod(a, b, 2*k+2, (l+r)/2, r);
        return op(vl, vr);
    }
    void update(int i, long long x) {
        i = n-1+i;
        node[i] = x;
        while(i > 0) {
            i = (i-1)/2;
            node[i] = op(node[2*i+1], node[2*i+2]);
        }
    }
    //[a,b)でa_i >= xなる最大のiを求める
    int maxindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        if(node[k] < x or r <= a or b <= l) return a-1;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vr = maxindex(a, b, x, 2*k+2, (l+r)/2, r);
            if(vr != a-1) return vr;
            else return maxindex(a, b, x, 2*k+1, l, (l+r)/2);
        }
    }
    //[a,b)でa_i >= xなる最小のiを求める
    int minindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        if(node[k] < x or r <= a or b <= l) return b;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vl = minindex(a, b, x, 2*k+1, l, (l+r)/2);
            if(vl != b) return vl;
            else return minindex(a, b, x, 2*k+2, (l+r)/2, r);
        }
    }
};
//遅延セグ木
struct LazySegTree {
    int n;
    vector<ll> node, lazy;
    const ll ex = 0, //セグ木上の積の単位元
             em = 0; //遅延評価木上の積の単位元
    function<ll(ll, ll)> fx = [](ll x, ll y) {return x+y;}, //セグ木上の積
                         fa = [](ll x, ll a) {return x+a;}, //遅延評価木からセグ木への作用
                         fm = [](ll a, ll b) {return a+b;}, //遅延評価木上の積
                         fp = [](ll a, ll n) {return a*n;}; //区間長の作用への影響

    LazySegTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        node.resize(2*n-1, ex);
        lazy.resize(2*n-1, em);
    }
    LazySegTree(vector<ll> a) {
        int sz = a.size();
        
        n = 1;
        while(n < sz) n *= 2;
        node.resize(2*n-1, ex);
        lazy.resize(2*n-1, em);

        for(int i = 0; i < sz; i++) node[n-1+i] = a[i];
        for(int i = n-2; i >= 0; i--) node[i] = fx(node[2*i+1], node[2*i+2]);
    }

    void eval(int k, int len) {
        if(lazy[k] == em) return;

        node[k] = fa(node[k], fp(lazy[k], len));
        if(k < n-1) {
            lazy[2*k+1] = fm(lazy[2*k+1], lazy[k]);
            lazy[2*k+2] = fm(lazy[2*k+2], lazy[k]);
        }
        lazy[k] = em;
    }
    //区間[a,b)を値xに更新
    void update(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(r <= a or b <= l) return;
        if(a <= l and r <= b) {
            lazy[k] = fm(lazy[k], x);
            eval(k, r - l);
        }else {
            update(a, b, x, 2*k+1, l, (l+r)/2);
            update(a, b, x, 2*k+2, (l+r)/2, r);
            node[k] = fx(node[2*k+1], node[2*k+2]);
        }
    }
    //区間[a,b)の積を取得
    ll prod(int a, int b, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(r <= a or b <= l) return ex;
        if(a <= l and r <= b) return node[k];
        
        ll vl = prod(a, b, 2*k+1, l, (l+r)/2);
        ll vr = prod(a, b, 2*k+2, (l+r)/2, r);
        return fx(vl, vr);
    }
    //[a,b)でa_i >= xなる最大のiを求める
    int maxindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(node[k] < x or r <= a or b <= l) return a-1;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vr = maxindex(a, b, x, 2*k+2, (l+r)/2, r);
            if(vr != a-1) return vr;
            else return maxindex(a, b, x, 2*k+1, l, (l+r)/2);
        }
    }
    //[a,b)でa_i >= xなる最小のiを求める
    int minindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(node[k] < x or r <= a or b <= l) return b;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vl = minindex(a, b, x, 2*k+1, l, (l+r)/2);
            if(vl != b) return vl;
            else return minindex(a, b, x, 2*k+2, (l+r)/2, r);
        }
    }
};
//平方分割
struct Backet {
    vector<ll> array;
    vector<ll> backet;
    int N, M;

    Backet(vector<ll> a) {
        array = a;
        N = a.size(), M = ceil(sqrt(N));
        
        backet.resize((N+M-1)/M);
        for(int i = 0; i < N; i++) {
            backet[i/M] += a[i];
        }
    }
    void add(int i, ll x) {
        array[i] += x;
        backet[i/M] += x;
    }
    //区間[i,j)の和
    ll getsum(int i, int j) {
        int l = i/M + 1, r = j/M;
        ll s = 0;
        if(l > r) {
            rep(k,i,j) s += array[k];
        }else {
            rep(k,i,l*M) s += array[k];
            rep(k,l,r) s += backet[k];
            rep(k,r*M,j) s += array[k];
        }
        return s;
    }
};
//最小共通祖先
struct LCA {
    Graph G;
    int N, LOG_N;
    vector<int> depth;
    vector<vector<int>> par;

    function<void(int)> dfs = [&](int v) {
        for(auto next_v : G[v]) {
            if(depth[next_v] != inf) continue;
            depth[next_v] = depth[v] + 1;
            par[0][next_v] = v;
            dfs(next_v);
        }
        return;
    };

    LCA(Graph &g) {
        G = g;
        N = G.size();
        depth.resize(N, inf);
        depth[0] = 0;
        LOG_N = 0;
        while((1<<LOG_N) < N) LOG_N++;
        par.resize(LOG_N+1, vector<int>(N));
        dfs(0);
        rep(i,1,LOG_N) {
            rep(j,0,N) {
                if(par[i-1][j] == -1) par[i][j] = -1;
                else par[i][j] = par[i-1][par[i-1][j]];
            }
        }
    }

    int ancestor(int u, int k) {
        int g = 0;
        while(k > 0) {
            if(k % 2 == 1) u = par[g][u];
            k /= 2;
            g++;
        }
        return u;
    }

    int lca(int u, int v) {
        int d1 = depth[u], d2 = depth[v];
        if(d1 < d2) v = ancestor(v, d2-d1);
        if(d1 > d2) u = ancestor(u, d1-d2);

        if(u == v) return u;
        for(int k = LOG_N; k >= 0; k--) {
            if(par[k][u] != par[k][v]) {
                u = par[k][u];
                v = par[k][v];
            }
        }
        return par[0][u];
    }

    int dist(int u, int v) {
        return depth[u] + depth[v] - 2*depth[lca(u, v)];
    }
};

void solve() {
}

int main() {
    int N; cin >> N;
    vll X1(N), Y1(N), X2(N), Y2(N);
    rep(i,0,N) {
        cin >> X1[i] >> Y1[i] >> X2[i] >> Y2[i];
    }
    auto x = compress2(X1, X2);
    auto y = compress2(Y1, Y2);
    int H = x.size(), W = y.size();
    
    vvi S(H, vi(W, 0));
    rep(i,0,N) {
        S[X1[i]][Y1[i]]++;
        S[X2[i]][Y2[i]]++;
        S[X1[i]][Y2[i]]--;
        S[X2[i]][Y1[i]]--;
    }
    
    rep(i,1,H) rep(j,0,W) S[i][j] += S[i-1][j];
    rep(i,0,H) rep(j,1,W) S[i][j] += S[i][j-1];
    ll ans = 0;
    rep(i,0,H) rep(j,0,W) {
        if(S[i][j] > 0) {
            ans += (x[i+1] - x[i])*(y[j+1] - y[j]);
        }
    }
    cout << ans << "\n";

    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 253560
final_rank: 13

code_snippet: #define _USE_MATH_DEFINES
#include<bits/stdc++.h>
#define OVERLOAD_REP(v1, v2, v3, v4, NAME, ...) NAME
#define REP1(i, n) for (int i = 0; (i) < (n); ++(i))
#define REP2(i, l, r) for (int i = (l); (i) < (r); ++(i))
#define REP3(i, l, r, d) for (int i = (l); (i) < (r); (i)+=(d))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_PRE(v1, v2, v3, v4, NAME, ...) NAME
#define PRE1(i, n) for (int i = (n)-1; (i) >= 0; --(i)) // [0,n)
#define PRE2(i, l, r) for (int i = (r)-1; (i) >= (l); --(i)) //[l,r)
#define PRE3(i, l, r, d) for (int i = (r)-1; (i) >= (l); (i)-=(d))
#define pre(...) OVERLOAD_PRE(__VA_ARGS__, PRE3, PRE2, PRE1)(__VA_ARGS__)
#define bg begin()
#define en end()
#define rbg rbegin()
#define ren rend()
#define all(x) x.bg,x.en
#define rall(x) x.rbg,x.ren
#define pf push_front
#define pb push_back
#define eb emplace_back
#define fir first
#define sec second
#define sz(x) ((int)(x).size())
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using sti = stack<int>;
using sei = set<int>;
using qi = queue<int>;
using qii = queue<pii>;
using dqi = deque<int>;
template<class t, class s> using umap = unordered_map<t,s>;
template<class t> using uset = unordered_set<t>;
template<class t> using mset = multiset<t>;
template<class t> using pq=priority_queue<t>;
template<class t> using pqg=priority_queue<t,vector<t>, greater<t>>;
template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;
template<class t> using vvvc=vc<vc<vc<t>>>;
using vi=vc<int>;
using vvi=vc<vc<int>>;
using vll=vc<ll>;
using vvll=vc<vc<ll>>;
using vd=vc<double>;
using vvd=vc<vc<double>>;
using vb=vc<bool>;
using vvb=vc<vc<bool>>;
using vch=vc<char>;
using vs=vc<string>;
const int inf = 1001001001;
const ll infl = 1LL << 60;
const ll mod = 998244353;
template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b; return true;} return false;}
template<class t,class u> bool chmin(t&a,u b){if(a>b){a=b; return true;} return false;}
void yes(){ cout << "Yes" << '\n'; }
void no(){ cout << "No" << '\n'; }

/* compress
    X を座圧して書き換える
    返り値: val(val[i]=座圧後のiの元の値)
    計算量: O(n log n)
*/
template <typename T>
vc<T> compress(vector<T> &X) {
    vc<T> vals = X;
    sort(all(vals));
    vals.erase(unique(all(vals)), vals.en);
    for(auto &xi: X) xi = lower_bound(all(vals), xi) - vals.bg;
    return vals;
}

int main() {
    int n; cin >> n;
    vi x1s(n),y1s(n),x2s(n),y2s(n),xs,ys;
    rep(i,n){
        cin >> x1s[i] >> y1s[i] >> x2s[i] >> y2s[i];
        xs.pb(x1s[i]);
        xs.pb(x2s[i]);
        ys.pb(y1s[i]);
        ys.pb(y2s[i]);
    }
    vi orix=compress(xs), oriy=compress(ys);
    for(auto &xi: x1s) xi = lower_bound(all(orix), xi) - orix.bg;
    for(auto &xi: x2s) xi = lower_bound(all(orix), xi) - orix.bg;
    for(auto &yi: y1s) yi = lower_bound(all(oriy), yi) - oriy.bg;
    for(auto &yi: y2s) yi = lower_bound(all(oriy), yi) - oriy.bg;
    int H=sz(orix),W=sz(oriy);
    vvll grid(H,vll(W));
    rep(i,n){
        int x1=x1s[i],y1=y1s[i],x2=x2s[i],y2=y2s[i];
        grid[x1][y1]++;
        grid[x2][y1]--;
        grid[x1][y2]--;
        grid[x2][y2]++;
    }
    rep(i,H)rep(j,W-1) grid[i][j+1]+=grid[i][j];
    rep(i,H-1)rep(j,W) grid[i+1][j]+=grid[i][j];
    ll ans=0;
    rep(i,H-1)rep(j,W-1)if(grid[i][j])ans+=(ll)(orix[i+1]-orix[i])*(oriy[j+1]-oriy[j]);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 128352
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i = 0; i < n; ++i)
using ll = long long;

int N;
int A[2000], B[2000], C[2000], D[2000];
int S[4000][4000];

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> N;
    rep(i,N) cin >> A[i] >> C[i] >> B[i] >> D[i];
    
    vector<ll> X(2 * N), Y(2 * N);
    rep(i,N) X[i] = A[i], X[i + N] = B[i], Y[i] = C[i], Y[i + N] = D[i];
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
    sort(Y.begin(), Y.end());
    Y.erase(unique(Y.begin(), Y.end()), Y.end());
    
    int Xs = X.size(), Ys = Y.size();
    rep(i,N) {
        int Ax = lower_bound(X.begin(), X.end(), A[i]) - X.begin(), Bx = lower_bound(X.begin(), X.end(), B[i]) - X.begin();
        int Cy = lower_bound(Y.begin(), Y.end(), C[i]) - Y.begin(), Dy = lower_bound(Y.begin(), Y.end(), D[i]) - Y.begin();
        ++S[Ax][Cy], --S[Bx][Cy], --S[Ax][Dy], ++S[Bx][Dy];
    }
    
    rep(i,Xs) rep(j,Ys - 1) S[i][j + 1] += S[i][j];
    rep(i,Xs - 1) rep(j,Ys) S[i + 1][j] += S[i][j];
    
    ll ans = 0;
    rep(i,Xs - 1) rep(j,Ys - 1) if(S[i][j] >= 1) ans += (X[i + 1] - X[i]) * (Y[j + 1] - Y[j]);
    
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 65952
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i = 0; i < n; ++i)
using ll = long long;

int main(void) {
    int N;
    cin >> N;
    
    vector<int> A(N), B(N), C(N), D(N);
    rep(i,N) cin >> A[i] >> C[i] >> B[i] >> D[i];
    
    vector<ll> X(2 * N), Y(2 * N);
    rep(i,N) X[i] = A[i], X[i + N] = B[i], Y[i] = C[i], Y[i + N] = D[i];
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
    sort(Y.begin(), Y.end());
    Y.erase(unique(Y.begin(), Y.end()), Y.end());
    
    int Xs = X.size(), Ys = Y.size();
    vector<vector<int>> S(Xs, vector<int>(Ys, 0));
    rep(i,N) {
        int Ax = lower_bound(X.begin(), X.end(), A[i]) - X.begin(), Bx = lower_bound(X.begin(), X.end(), B[i]) - X.begin();
        int Cy = lower_bound(Y.begin(), Y.end(), C[i]) - Y.begin(), Dy = lower_bound(Y.begin(), Y.end(), D[i]) - Y.begin();
        ++S[Ax][Cy], --S[Bx][Cy], --S[Ax][Dy], ++S[Bx][Dy];
    }
    
    rep(i,Xs) rep(j,Ys - 1) S[i][j + 1] += S[i][j];
    rep(i,Xs - 1) rep(j,Ys) S[i + 1][j] += S[i][j];
    
    ll ans = 0;
    rep(i,Xs - 1) rep(j,Ys - 1) if(S[i][j] >= 1) ans += (X[i + 1] - X[i]) * (Y[j + 1] - Y[j]);
    
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 65880
final_rank: 4

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
	int N;
	cin >> N;
	vector<vector<long long>> lef(N, vector<long long>(2)), rig(lef);
	vector<long long> tmp;
	for(int i = 0; i < N; i++){
		cin >> lef[i][0] >> lef[i][1];
		cin >> rig[i][0] >> rig[i][1];
		for(int j = 0; j < 2; j++){
			tmp.push_back(lef[i][j]);
			tmp.push_back(rig[i][j]);
		}
	}
	sort(tmp.begin(), tmp.end());
	tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
	
	vector<vector<int>> grid(tmp.size(), vector<int>(tmp.size(), 0));
	for(int i = 0, a, b, c, d; i < N; i++){
		a = lower_bound(tmp.begin(), tmp.end(), lef[i][0]) - tmp.begin();
		b = lower_bound(tmp.begin(), tmp.end(), lef[i][1]) - tmp.begin();
		c = lower_bound(tmp.begin(), tmp.end(), rig[i][0]) - tmp.begin();
		d = lower_bound(tmp.begin(), tmp.end(), rig[i][1]) - tmp.begin();
		grid[a][b]++;
		grid[a][d]--;
		grid[c][b]--;
		grid[c][d]++;
	}
	for(int i = 0, s = tmp.size(); i < s; i++)
		for(int j = 1; j < s; j++) grid[i][j] += grid[i][j - 1];
	for(int i = 0, s = tmp.size(); i < s; i++)
		for(int j = 1; j < s; j++) grid[j][i] += grid[j - 1][i];
	
	long long ans = 0;
	for(int i = 0, s = tmp.size(); i < s - 1; i++){
		for(int j = 0; j < s - 1;){
			if(grid[i][j] > 0){
				int n = j;
				while(grid[i][++j] > 0);
				ans += (tmp[j] - tmp[n]) * (tmp[i + 1] - tmp[i]);
			}else j++;
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 253952
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

using LL = long long;

int main() {
  int N; cin >> N;
  vector<int> X(2 * N), Y(2 * N);
  set<int> setX, setY;
  for (int i = 0; i < 2 * N; i+= 2) {
    cin >> X[i] >> Y[i] >> X[i + 1] >> Y[i + 1];
    setX.insert(X[i]); setX.insert(X[i + 1]); setY.insert(Y[i]); setY.insert(Y[i + 1]);
  }

  vector<int> uX(setX.begin(), setX.end());
  vector<int> uY(setY.begin(), setY.end());
  sort(uX.begin(), uX.end());
  sort(uY.begin(), uY.end());

  int W = uX.size();
  int H = uY.size();
  vector<vector<int>> imos(H, vector<int>(W,0)); //imos[i][j] = uY[i]からuY[i + 1], uX[i]からuX[i + 1]の長方形ブロックについて
  for (int i = 0; i < N; ++i) {
    int c1 = lower_bound(uX.begin(), uX.end(), X[2 * i]) - uX.begin();
    int c2 = lower_bound(uX.begin(), uX.end(), X[2 * i + 1]) - uX.begin();
    int r1 = lower_bound(uY.begin(), uY.end(), Y[2 * i]) - uY.begin();
    int r2 = lower_bound(uY.begin(), uY.end(), Y[2 * i + 1]) - uY.begin();
    imos[r1][c1]++;
    imos[r1][c2]--;
    imos[r2][c1]--;
    imos[r2][c2]++;
  }

  for (int i = 0; i < H; ++i) {
    for (int j = 1; j < W; ++j) {
      imos[i][j] += imos[i][j-1];
    }
  }
  for (int j = 0; j < W; ++j) {
    for (int i = 1; i < H; ++i) {
      imos[i][j] += imos[i - 1][j];
    }
  }
  LL total_area = 0;
  for (int i = 0; i < H-1; ++i) {
    for (int j = 0; j < W-1; ++j) {
      if (imos[i][j] > 0) {
        LL width = uX[j + 1] - uX[j];
        LL height = uY[i + 1] - uY[i];
        total_area += width * height;
      }
    }
  }

  cout << total_area << endl;
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 66072
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){
    ll N; cin>>N;
    vector<ll> X1(N),Y1(N),X2(N),Y2(N);
    for(int i=0;i<N;i++) cin>>X1[i]>>Y1[i]>>X2[i]>>Y2[i];

    vector<ll> Xatsu,Yatsu;
    for(int i=0;i<N;i++){
        Xatsu.push_back(X1[i]);
        Yatsu.push_back(Y1[i]);
        Xatsu.push_back(X2[i]);
        Yatsu.push_back(Y2[i]);
    }
    sort(Xatsu.begin(),Xatsu.end());
    sort(Yatsu.begin(),Yatsu.end());
    Xatsu.erase(unique(Xatsu.begin(),Xatsu.end()),Xatsu.end());
    Yatsu.erase(unique(Yatsu.begin(),Yatsu.end()),Yatsu.end());

    vector<vector<ll>> imos(Xatsu.size(),vector<ll>(Yatsu.size(),0));
    for(int i=0;i<N;i++){
        ll x1=lower_bound(Xatsu.begin(),Xatsu.end(),X1[i])-Xatsu.begin();
        ll y1=lower_bound(Yatsu.begin(),Yatsu.end(),Y1[i])-Yatsu.begin();
        ll x2=lower_bound(Xatsu.begin(),Xatsu.end(),X2[i])-Xatsu.begin();
        ll y2=lower_bound(Yatsu.begin(),Yatsu.end(),Y2[i])-Yatsu.begin();

        imos[x1][y1]++;
        imos[x1][y2]--;
        imos[x2][y1]--;
        imos[x2][y2]++;
    }
    for(int i=0;i<Xatsu.size();i++){
        for(int j=1;j<Yatsu.size();j++){
            imos[i][j]+=imos[i][j-1];
        }
    }
    for(int i=0;i<Yatsu.size();i++){
        for(int j=1;j<Xatsu.size();j++){
            imos[j][i]+=imos[j-1][i];
        }
    }

    ll ans=0;
    for(int i=0;i<Xatsu.size()-1;i++){
        for(int j=0;j<Yatsu.size()-1;j++){
            if(imos[i][j]>0) ans+=(Xatsu[i+1]-Xatsu[i])*(Yatsu[j+1]-Yatsu[j]);
        }
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 160
memory_kb: 128424
final_rank: 9

code_snippet: #include <iostream>
#include <algorithm>

#define N (2000* 2 + 1)

using namespace std;

struct Node{
	int x, y1, y2;
	int val;
	Node(int x = 0, int y1 = 0, int y2 = 0, int val = 0) : x(x), y1(y1), y2(y2), val(val){}
} node[N];

int cmp(const Node& l, const Node& r){
	if(l.x != r.x) return l.x < r.x;
	else return l.val > r.val;
}

long long y[N];
int n, q;
long long tree[N << 2];
long long lazy[N << 2];

// root == 1
void build(int idx, int start, int end){

	if(start == end){
		tree[idx] = 0;
		lazy[idx] = 0;
	} 
	else{
		int mid = (start + end) / 2;
		build(idx * 2, start, mid);
		build(idx * 2 + 1, mid + 1, end);
		tree[idx] = 0;
		lazy[idx] = 0;
	}
}


void update(int idx, int start, int end, int l, int r, int val){
	
	if(lazy[idx] != 0){
		tree[idx] += lazy[idx];
		if(start != end){
			lazy[idx * 2] += lazy[idx];
			lazy[idx * 2 + 1] += lazy[idx];
		}
		lazy[idx] = 0;
	}
	
	if(start > end || start > r || end < l) return;
//	cout << start << " " << end << " " << l << " " << r << endl;
	
	if(start >= l && end <= r){
		tree[idx] += val;
		if(start != end){
			lazy[idx * 2] += val;
			lazy[idx * 2 + 1] += val;
		}
		return;
	}
	
	int mid = (start + end) / 2;
	update(idx * 2, start, mid, l , r, val);
	update(idx * 2 + 1, mid + 1, end, l , r, val);
	tree[idx] = min(tree[idx * 2], tree[idx * 2 + 1]);
}

long long query(int idx, int start, int end, int l, int r){
	if(start > end || start > r || end < l) return 0;
	
	if(lazy[idx] != 0){
		tree[idx] += lazy[idx];
		if(start != end){
			lazy[idx * 2] += lazy[idx];
			lazy[idx * 2 + 1] += lazy[idx];
		}
		lazy[idx] = 0;
	}
	if(start >= l && end <= r){
		if(tree[idx]){
//			cout << y[end + 1 - 1] << " " << y[start - 1] << endl;
			return (y[end + 1 - 1] - y[start - 1]);
		} 
//		else return 0;
	}
	if(start == end){
		if(tree[idx]) return (y[end + 1 - 1] - y[start - 1]);
		else return 0;
	}
	int mid = (start + end) / 2;
	long long p1 = query(idx * 2, start, mid, l, r);
	long long p2 = query(idx * 2 + 1, mid + 1, end, l, r);
	return (p1 + p2);
}

int main(){
	
	int x1, y1, x2, y2;
	int node_idx = 0, y_idx = 0;
	long long ans = 0;
	
	cin >> n;
	
	build(1, 1, N);
	
	for(int i = 0; i < n; i++){
		cin >> x1 >> y1 >> x2 >> y2;
		node[node_idx++] = Node(x1, y1, y2, 1); 
		node[node_idx++] = Node(x2, y1, y2, -1);
		y[y_idx++] = y1;
		y[y_idx++] = y2;
	}
	sort(node, node + n * 2, cmp);
	sort(y, y + n * 2);
	
	for(int i = 0; i < n * 2 - 1 ; i++){
		int L = lower_bound(y, y + n * 2, node[i].y1) - y + 1;
		int R = lower_bound(y, y + n * 2, node[i].y2) - y;
		
//		cout << L << " " << R << " ";
		
		update(1, 1, n * 2 - 1, L, R, node[i].val);
/*		
		for(int j = 0; j < 7; j++){
			cout << tree[j + 1] << " ";
		}
		cout << endl;
*/	
//		cout << (node[i + 1].x - node[i].x) << " " << query(1, 1, 2 * n - 1, 1, 2 * n - 1) << endl;
		ans += (node[i + 1].x - node[i].x) * query(1, 1, 2 * n - 1, 1, 2 * n - 1);	
		
	}
	

	
	cout << ans << endl;
	
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3656
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
const ll INF = LLONG_MAX / 4;
const ll mod1 = 1000000007;
const ll mod9 = 998244353;
const ll Hash = 10000000000000061;
#define all(a) (a).begin(),(a).end()
#define rep(i, n) for (ll i = 0; (i) < (n); ++(i))
#define reps(i, l, r) for(ll i = (l); (i) < (r); ++(i))
ll dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
ll dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T>
bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; }
    return false;
}
template <typename T>
bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; }
    return false;
}

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
class Point {
public:
    ld x;
    ld y;
    Point(ld _x = 0, ld _y = 0) : x(_x), y(_y) {}
    Point operator+(Point p) { return Point(x + p.x, y + p.y); }
    Point operator-(Point p) { return Point(x - p.x, y - p.y); }
    Point operator*(ld a) { return Point(a * x, a * y); }
    Point operator/(ld a) { return Point(x / a, y / a); }

    ld abs() { return sqrt(norm()); }
ld norm() { return x * x + y * y; }

    bool operator<(const Point& p) const {
        return !equals(x, p.x) ? x < p.x : y < p.y;
    }
    bool operator==(const Point& p) const {
        return fabs(x - p.x) < (1e-10) && fabs(y - p.y) < (1e-10);
    }
};
typedef Point Vector;
struct Segment {
    Point A;
    Point B;
};
typedef Segment Line;
class Circle {
public:
    Point C;
    ld r;
    Circle(Point C = Point(), ld r = 0.0) : C(C), r(r) {}
};
typedef vector<Point> Polygon;

void solve(){
    ll N; cin >> N;
    vector<pll> z(N*2);
    vector<ll> x(N*2), y(N*2);
    rep(i, N*2){
        ll a, b; cin >> a >> b;
        z[i] = {a, b};
        x[i] = a, y[i] = b;
    }
    sort(all(x));
    x.erase(unique(all(x)), x.end());
    sort(all(y));
    y.erase(unique(all(y)), y.end());
    ll X = x.size(), Y = y.size();
    rep(i, N*2){
        ll a = lower_bound(all(x), z[i].first) - x.begin();
        ll b = lower_bound(all(y), z[i].second) - y.begin();
        z[i] = {a, b};
    }
    vector<vector<ll>> imos(X, vector<ll>(Y, 0));
    rep(i, N){
        ll a = z[i*2].first, b = z[i*2].second, c = z[i*2+1].first, d = z[i*2+1].second;
        imos[a][b]++; imos[c][d]++; imos[a][d]--; imos[c][b]--;
    }

    rep(i, X){
        rep(k, Y-1){
            imos[i][k+1] += imos[i][k];
        }
    }
    rep(k, Y){
        rep(i, X-1){
            imos[i+1][k] += imos[i][k];
        }
    }
    ll ans = 0;
    rep(i, X-1){
        rep(k, Y-1){
            if(imos[i][k]>0){
                ans += (x[i+1] - x[i]) * (y[k+1] - y[k]);
            }
        }
    }
    cout << ans << endl;
}

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    
    solve();
}
accuracy: 1
time_ms: 190
memory_kb: 128340
final_rank: 10

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

int main(){
    ll n;
    cin >> n;
    vc<pair<pll, pll>> rect(n);
    rep(i, n){
        ll x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        rect[i] = make_pair(make_pair(x1, y1), make_pair(x2, y2));
    }

    vl xs, ys;
    rep(i, n){
        xs.push_back(rect[i].first.first);
        xs.push_back(rect[i].second.first);

        ys.push_back(rect[i].first.second);
        ys.push_back(rect[i].second.second);
    }

    sort(nall(xs));
    sort(nall(ys));

    vc_unique(xs);
    vc_unique(ys);

    vc<pair<pll, pll>> rectComp(n);
    rep(i, n){
        rectComp[i].first.first = lower_bound(nall(xs), rect[i].first.first) - xs.begin();
        rectComp[i].second.first = lower_bound(nall(xs), rect[i].second.first) - xs.begin();

        rectComp[i].first.second = lower_bound(nall(ys), rect[i].first.second) - ys.begin();
        rectComp[i].second.second = lower_bound(nall(ys), rect[i].second.second) - ys.begin();
    }

    vvl grid(xs.size() + 1, vl(ys.size() + 1, 0));
    rep(i, n){
        auto [p1, p2] = rectComp[i];
        auto [x1, y1] = p1;
        auto [x2, y2] = p2;

        grid[x1][y1]++;
        grid[x2][y1]--;
        grid[x1][y2]--;
        grid[x2][y2]++;
    }

    rep(i, xs.size()) rep(j, ys.size()){
        grid[i+1][j] += grid[i][j];
    }

    rep(i, xs.size()) rep(j, ys.size()){
        grid[i][j+1] += grid[i][j];
    }

    ll ans = 0;
    rep(i, xs.size()-1) rep(j, ys.size()){
        if(grid[i][j] > 0){
            ans += (xs[i+1] - xs[i])*(ys[j+1] - ys[j]);
        }
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 128376
final_rank: 7

code_snippet: #pragma region Macros
#include <bits/stdc++.h>

#include <atcoder/all>
using namespace std;
using namespace atcoder;
using lint = long long;
using mint = modint998244353;
using ull = unsigned long long;
using ld = long double;
using int128 = __int128_t;
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define uniqv(v) v.erase(unique(all(v)), v.end())
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define log(x) cout << x << endl
#define logfixed(x) cout << fixed << setprecision(10) << x << endl;
#define logy(bool)         \
  if (bool) {              \
    cout << "Yes" << endl; \
  } else {                 \
    cout << "No" << endl;  \
  }

ostream &operator<<(ostream &dest, __int128_t value) {
  ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(ios_base::badbit);
    }
  }
  return dest;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    os << v[i] << (i + 1 != (int)v.size() ? " " : "");
  }
  return os;
}

template <typename T>
ostream &operator<<(ostream &os, const set<T> &set_var) {
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << itr->first << " -> " << itr->second << "\n";
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

void out() { cout << '\n'; }
template <class T, class... Ts>
void out(const T &a, const Ts &...b) {
  cout << a;
  (cout << ... << (cout << ' ', b));
  cout << '\n';
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}

inline void in(void) { return; }
template <typename First, typename... Rest>
void in(First &first, Rest &...rest) {
  cin >> first;
  in(rest...);
  return;
}

template <typename T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

vector<lint> dx8 = {1, 1, 0, -1, -1, -1, 0, 1};
vector<lint> dy8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<lint> dx4 = {1, 0, -1, 0};
vector<lint> dy4 = {0, 1, 0, -1};

#pragma endregion

int main() {
  cin.tie(0)->sync_with_stdio(0);
  int n;
  in(n);
  vector<lint> xl(n), yl(n), xr(n), yr(n);
  vector<lint> tx, ty;

  rep(i, n) {
    in(xl[i], yl[i], xr[i], yr[i]);
    tx.emplace_back(xl[i]);
    tx.emplace_back(xr[i]);
    tx.emplace_back(xl[i] + 1);
    tx.emplace_back(xr[i] + 1);
    ty.emplace_back(yl[i]);
    ty.emplace_back(yr[i]);
    ty.emplace_back(yl[i]) + 1;
    ty.emplace_back(yr[i]) + 1;
  }

  sort(all(tx));
  sort(all(ty));
  uniqv(tx);
  uniqv(ty);

  rep(i, n) {
    xl[i] = distance(tx.begin(), lower_bound(all(tx), xl[i]));
    xr[i] = distance(tx.begin(), lower_bound(all(tx), xr[i]));
    yl[i] = distance(ty.begin(), lower_bound(all(ty), yl[i]));
    yr[i] = distance(ty.begin(), lower_bound(all(ty), yr[i]));
  }
  int h = ty.size();
  int w = tx.size();
  vector g(h, vector(w, int(0)));
  rep(i, n) {
    g[yl[i]][xl[i]]++;
    g[yl[i]][xr[i]]--;
    g[yr[i]][xl[i]]--;
    g[yr[i]][xr[i]]++;
  }

  rep(i, h) {
    rep(j, w - 1) {
      g[i][j + 1] += g[i][j];
    }
  }

  rep(j, w) {
    rep(i, h - 1) {
      g[i + 1][j] += g[i][j];
    }
  }

  lint res = 0;
  rep(i, h) {
    rep(j, w) {
      if (g[i][j] > 0) {
        res += (ty[i + 1] - ty[i]) * (tx[j + 1] - tx[j]);
      }
    }
  }

  out(res);
}
accuracy: 1
time_ms: 200
memory_kb: 128768
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i< (n); ++i)
using ll = long long;
template<typename T=int>
struct CC {
	bool initialized;
	vector<T> xs;
	CC(): initialized(false) {}
	void add(T x) { xs.push_back(x);}
	void init() {
		sort(xs.begin(), xs.end());
		xs.erase(unique(xs.begin(),xs.end()),xs.end());
		initialized = true;
	}
	int operator()(T x) {
		if (!initialized) init();
		return upper_bound(xs.begin(), xs.end(), x) - xs.begin() - 1;
	}
	T operator[](int i) {
		if (!initialized) init();
		return xs[i];
	}
	int size() {
		if (!initialized) init();
		return xs.size();
	}
};
int main() {
  int n; cin >> n;
	vector<ll> x1(n), y1(n), x2(n), y2(n);
	CC<ll> X, Y;
  rep(i, n){
		cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
		X.add(x1[i]);X.add(x2[i]);
		Y.add(y1[i]);Y.add(y2[i]);
	}
	vector<vector<int>> S(2001, vector<int>(2001, 0));
	rep(i, n){
		S[X(x1[i])][Y(y1[i])]++;
		S[X(x1[i])][Y(y2[i])]--;
		S[X(x2[i])][Y(y1[i])]--;
		S[X(x2[i])][Y(y2[i])]++;
	}
	rep(i, 2000)rep(j, 2001){
		S[i+1][j]+=S[i][j];
	}
	rep(i, 2001)rep(j, 2000){
		S[i][j+1]+=S[i][j];
	}
	ll ans = 0;
  rep(i, 2001)rep(j, 2001){
		if(S[i][j] >= 1){
			ans += (X[i+1]-X[i])*(Y[j+1]-Y[j]);
		}
	}
	cout << ans << endl;


		
}
accuracy: 0.82
time_ms: 10
memory_kb: 18956
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i< (n); ++i)
using ll = long long;
template<typename T=int>
struct CC {
	bool initialized;
	vector<T> xs;
	CC(): initialized(false) {}
	void add(T x) { xs.push_back(x);}
	void init() {
		sort(xs.begin(), xs.end());
		xs.erase(unique(xs.begin(),xs.end()),xs.end());
		initialized = true;
	}
	int operator()(T x) {
		if (!initialized) init();
		return upper_bound(xs.begin(), xs.end(), x) - xs.begin() - 1;
	}
	T operator[](int i) {
		if (!initialized) init();
		return xs[i];
	}
	int size() {
		if (!initialized) init();
		return xs.size();
	}
};
int main() {
  int n; cin >> n;
	vector<ll> x1(n), y1(n), x2(n), y2(n);
	CC X, Y;
  rep(i, n){
		cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
		X.add(x1[i]);X.add(x2[i]);
		Y.add(y1[i]);Y.add(y2[i]);
	}
	vector<vector<int>> S(2001, vector<int>(2001, 0));
	rep(i, n){
		S[X(x1[i])][Y(y1[i])]++;
		S[X(x1[i])][Y(y2[i])]--;
		S[X(x2[i])][Y(y1[i])]--;
		S[X(x2[i])][Y(y2[i])]++;
	}
	rep(i, 2000)rep(j, 2001){
		S[i+1][j]+=S[i][j];
	}
	rep(i, 2001)rep(j, 2000){
		S[i][j+1]+=S[i][j];
	}
	ll ans = 0;
  rep(i, 2001)rep(j, 2001){
		if(S[i][j] >= 1){
			ans += (X[i+1]-X[i])*(Y[j+1]-Y[j]);
		}
	}
	cout << ans << endl;


		
}
accuracy: 0.48
time_ms: 10
memory_kb: 18956
final_rank: 20

code_snippet: #pragma GCC optimize("Ofast,unroll-loops")
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using u8=uint8_t;
using u16=uint16_t;
using u32=uint32_t;
using u64=uint64_t;
using i128=__int128;
using u128=unsigned __int128;
using ld=long double;
using str=string;
template<class F>using fn=function<F>;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
#define eval3(a,b,c,d,...)d
#define eval4(a,b,c,d,e,...)e
#define eval5(a,b,c,d,e,f,...)f
#define eval6(a,b,c,d,e,f,g,...)g
template<class T>using vc=vector<T>;
template<class T>using vvc=vc<vc<T>>;
template<class T>using vvvc=vc<vvc<T>>;
template<class T>using vvvvc=vc<vvvc<T>>;
#define vv(T,x,h,...)vvc<T>x(h,vc<T>(__VA_ARGS__));
#define vvv(T,x,h,w,...)vvvc<T>x(h,vector(w,vc<T>(__VA_ARGS__)));
#define vvvv(T,x,a,b,c,...)vvvvc<T>x(a,vector(b,vector(c,vc<T>(__VA_ARGS__))));
using vi=vc<int>;
using vl=vc<ll>;
template<class T>using pq=priority_queue<T>;
template<class T>using pqg=priority_queue<T,vc<T>,greater<T>>;
template<class T>using max_queue=pq<T>;
template<class T>using min_queue=pqg<T>;
#define loop while(1)
#define rep0(n)for(ll __=0;__<ll(n);++__)
#define rep1(i,n)for(ll i=0;i<ll(n);++i)
#define rep2(i,a,b)for(ll i=a;i<ll(b);++i)
#define rep3(i,a,b,c)for(ll i=a;i<ll(b);i+=c)
#define rep(...)eval4(__VA_ARGS__,rep3,rep2,rep1,rep0)(__VA_ARGS__)
#define repr1(i,n)for(ll i=n;i-->0;)
#define repr2(i,a,b)for(ll i=b;i-->ll(a);)
#define repr(...)eval3(__VA_ARGS__,repr2,repr1,rep0)(__VA_ARGS__)
#define per(...)repr(__VA_ARGS__)
#define rrep1(i,n)for(ll i=n;i>0;i--)
#define rrep2(i,a,b)for(ll i=a;i>ll(b);i--)
#define rrep3(i,a,b,c)for(ll i=a;i>ll(b);i+=c)
#define rrep(...)eval4(__VA_ARGS__,rrep3,rrep2,rrep1,rep0)(__VA_ARGS__)
#define iter1(a,A)for(auto a:A)
#define iter2(a,b,A)for(auto[a,b]:A)
#define iter3(a,b,c,A)for(auto[a,b,c]:A)
#define iter4(a,b,c,d,A)for(auto[a,b,c,d]:A)
#define iter5(a,b,c,d,e,A)for(auto[a,b,c,d,e]:A)
#define iter(...)eval6(__VA_ARGS__,iter5,iter4,iter3,iter2,iter1)(__VA_ARGS__)
#define iter_mut1(a,A)for(auto&a:A)
#define iter_mut2(a,b,A)for(auto&[a,b]:A)
#define iter_mut3(a,b,c,A)for(auto&[a,b,c]:A)
#define iter_mut4(a,b,c,d,A)for(auto&[a,b,c,d]:A)
#define iter_mut5(a,b,c,d,e,A)for(auto&[a,b,c,d,e]:A)
#define iter_mut(...)eval6(__VA_ARGS__,\
iter_mut5,iter_mut4,iter_mut3,iter_mut2,iter_mut1)(__VA_ARGS__)
#define iter_ref1(a,A)for(const auto&a:A)
#define iter_ref2(a,b,A)for(const auto&[a,b]:A)
#define iter_ref3(a,b,c,A)for(const auto&[a,b,c]:A)
#define iter_ref4(a,b,c,d,A)for(const auto&[a,b,c,d]:A)
#define iter_ref5(a,b,c,d,e,A)for(const auto&[a,b,c,d,e]:A)
#define iter_ref(...)eval6(__VA_ARGS__,\
iter_ref5,iter_ref4,iter_ref3,iter_ref2,iter_ref1)(__VA_ARGS__)
#define endl '\n'
#define elif else if
#define fi first
#define se second
#define be begin()
#define en end()
#define rbe rbegin()
#define ren rend()
#define MP make_pair
#define MT make_tuple
#define pb push_back
#define eb emplace_back
#define emp emplace
#define fr front()
#define bk back()
#define stoi stoll
#define ALL(a)(a).be,(a).en
#define RALL(a)(a).rbe,(a).ren
#define LB(a,x)std::lower_bound(ALL(a),(x))
#define UB(a,x)std::upper_bound(ALL(a),(x))
#define LBI(a,x)LB(a,x)-(a).be
#define UBI(a,x)UB(a,x)-(a).be
#define lb(a,x)std::lower_bound(ALL(a),(x))
#define ub(a,x)std::upper_bound(ALL(a),(x))
#define lbi(a,x)LB(a,x)-(a).be
#define ubi(a,x)UB(a,x)-(a).be
#define len(a)ll(a.size())
#define PI 3.14159265358979323846
template<class T>
int ctz(T x){return __builtin_ctzll(x);}
int ctz(u128 x){
	u64 y=x&u64(-1);
	return y?ctz(y):64+ctz(u64(x>>64));
}
int ctz(i128 x){return ctz((u128)x);}
template<class T>
int clz(T x){return __builtin_clzll(x);}
int clz(u128 x){
	u64 y=x>>64;
	return y?clz(y):64+clz((u64)x);
}
int clz(i128 x){return clz((u128)x);}
template<class T>int lsb(T x){return x?ctz(x):-1;}
template<class T>int msb(T x){return x?63-clz(x):-1;}
int msb(u128 x){return x?127-clz(x):-1;}
int msb(i128 x){return msb((u128)x);}
template<class T>int bitlen(T x){return msb(x)+1;}
template<class T>
ll popcnt(T x){return __builtin_popcountll(x);}
ll popcnt(u128 x){return popcnt(u64(x&u64(-1)))+popcnt(u64(x>>64));}
ll popcnt(i128 x){return popcnt((u128)x);}
#define popcount(x)popcnt(x)
template<class T>
int parity(T x){return __builtin_parityll(x);}
template<class T,class U>
bool chmax(T&a,U b){return b>a?a=b,1:0;}
template<class T,class U>
bool chmin(T&a,U b){return b<a?a=b,1:0;}
template<class...T>
constexpr auto MIN(T... a){
	return min(initializer_list<common_type_t<T...>>{a...});
}
template<class...T>
constexpr auto MAX(T... a){
	return max(initializer_list<common_type_t<T...>>{a...});
}
template<class T>
T max(const vc<T>&a){return *max_element(ALL(a));}
template<class T>
T min(const vc<T>&a){return *min_element(ALL(a));}
template<class T>
T max(const vvc<T>&a){
	T y=max(a[0]);
	rep(i,1,len(a))chmax(y,max(a[i]));
	return y;
}
template<class T>
T min(const vvc<T>&a){
	T y=min(a[0]);
	rep(i,1,len(a))chmin(y,min(a[i]));
	return y;
}
constexpr int GCD(){return 0;}
template<class T>constexpr T GCD(T x){return x;}
template<class T,class...Ts>
constexpr auto GCD(T a,Ts...b){
	if constexpr(!sizeof...(Ts))return a;
	else {
		using X=common_type_t<T,common_type_t<Ts...>>;
		return gcd<X>(a,GCD(b...));
	}
}
template<class T>
int signum(T x){return x<0?-1:x>0;}
template<class A>
void sort(A&a){sort(ALL(a));}
template<class A>
void rsort(A&a){sort(RALL(a));}
template<class A>
void reverse(A&a){reverse(ALL(a));}
#define UNIQUE(a)sort(a),a.erase(unique(ALL(a)),a.en)
template<class A>
A unique(A a){
	UNIQUE(a);
	return a;
}
template<class A,class F>
void filter(A&a,F f){
	a.erase(remove_if(ALL(a),[&](auto&x){return !f(x);}),a.en);
}
template<class T,class U>
common_type_t<T,U>ceil_div(T a,U b){
	return a/b+((a^b)>0&&a%b);
};
template<class T,class U>
common_type_t<T,U>floor_div(T a,U b){
	return a/b-((a^b)<0&&a%b);
};
template<class T,class U>
T sum(const vc<U>&a){return accumulate(ALL(a),T{});}
template<class T>
T sum(const vc<T>&a){return sum<T,T>(a);}
template<class T>T sum(){return T{};}
template<class...T>
common_type_t<T...>sum(T...a){return(common_type_t<T...>{}+...+a);}
template<class T=ll>
constexpr T ten(int k){return k?ten<T>(k-1)*10:1;}
template<class A>
bool all(A a){
	iter_ref(x,a)if(!x)return 0;
	return 1;
}
template<class A,class F>
bool all(A a,F f){
	iter_ref(x,a)if(!f(x))return 0;
	return 1;
}
template<class A>
bool any(A a){
	iter_ref(x,a)if(x)return 1;
	return 0;
}
template<class A,class F>
bool any(A a,F f){
	iter_ref(x,a)if(f(x))return 1;
	return 0;
}
template<class T>
vc<T>get(const vc<T>&a,const vc<int>&p){
	int n=len(p);
	vc<T>b(n);
	rep(i,n)b[i]=a[p[i]];
	return b;
}
vc<char>get(const string&a,const vc<int>&p){
	int n=len(p);
	vc<char>b(n);
	rep(i,n)b[i]=a[p[i]];
	return b;
}
vc<int>argperm(const vc<int>&a){
	int n=len(a);
	vc<int>p(n);
	rep(i,n)p[a[i]]=i;
	return p;
}
template<class A>
vc<int>argsort(const A&a,bool desc=0,bool rev=0){
	int n=len(a);
	vc<int>p(n);
	rep(i,n)p[i]=i;
	sort(ALL(p),[&](int i,int j){
		if(a[i]!=a[j])return desc?a[i]>a[j]:a[i]<a[j];
		return rev?i>j:i<j;
	});
	return p;
}
template<class T=int>
vc<T>iota(int n,T x={}){
	vc<T>a(n);
	rep(i,n)a[i]=i+x;
	return a;
}
template<class T>
T POP(vc<T>&a){T x=a.bk;a.pop_back();return x;}
i128 abs(i128 x){return x<0?-x:x;}
string to_string(u128 x){
	if(x==0)return "0";
	string s;
	while(x){
		s+=x%10+'0';
		x/=10;
	}
	reverse(s);
	return s;
}
string to_string(i128 x){
	if(x==0)return "0";
	bool neg=0;
	if(x<0){neg=1,x=-x;}
	string s;
	while(x){
		s+=x%10+'0';
		x/=10;
	}
	if(neg)s+='-';
	reverse(s);
	return s;
}
template<class T,class U,class F>
auto binarysearch(F f,T ok0,U ng0,bool check=1){
	using X=common_type_t<T,U>;
	X ok=ok0,ng=ng0;
	if(check)assert(f(ok));
	while(abs(ok-ng)>1){
		X x=(ok+ng)/2;
		(f(x)?ok:ng)=x;
	}
	return ok;
}
template<class T,class U,class F>
auto binarysearch(T ok0,U ng0,F f,bool check=1){
	using X=common_type_t<T,U>;
	X ok=ok0,ng=ng0;
	if(check)assert(f(ok));
	while(abs(ok-ng)>1){
		X x=(ok+ng)/2;
		(f(x)?ok:ng)=x;
	}
	return ok;
}
template<class F>
struct REC{
	F f;
	REC(F f):f(f){}
	template<class...X>
	auto operator()(X...x){return f(f,x...);}
};
namespace io{
template<class T>
constexpr bool is_128=is_same_v<T,i128>||is_same_v<T,u128>;
constexpr int N=1<<16;
struct I{
char b[N],*r=b+N,*p=r;
constexpr inline void load(int need){
	if(int d=r-p;d<need){
		d=fread(copy_n(p,d,b),1,p-b,stdin);
		p=b;
	}
}
void skip(){while(*p<=' ')++p;}
void sc(char&c){
	load(5);
	skip();
	c=*p++;
}
void sc(string&s){
	s.clear();
	load(5);
	skip();
	do{
		s+=*p++;
		load(1);
	}while(*p>' ');
	++p;
}
void sc(double&x){
	string s;
	sc(s);
	x=stod(s);
}
template<class T>
enable_if_t<is_integral_v<T>>sc(T&x){
	load(25);
	skip();
	bool neg=0;
	if(*p=='-')neg=1,++p;
	x=0;
	bool ok=0;
	while(1){
		int d=0;
		for(int i=0;i<9;i++){
			if(*p<=' '){
				ok=1;
				if(i)x=x*ten<int>(i)+d;
				++p;
				break;
			}
			d=d*10+(*p++-'0');
		}
		if(ok)break;
		x=x*ten<int>(9)+d;
	}
	if(neg)x=-x;
}
template<class T>
enable_if_t<is_128<T>>sc(T&x){
	load(45);
	skip();
	bool neg=0;
	if(*p=='-')neg=1,++p;
	x=0;
	while(1){
		uint64_t d;
		memcpy(&d,p,8);
		d-=0x3030303030303030;
		if(d&0x8080808080808080)break;
		d=(d*10+(d>>8))&0xff00ff00ff00ff;
		d=(d*100+(d>>16))&0xffff0000ffff;
		d=(d*10000+(d>>32))&0xffffffff;
		x=x*100000000+d;
		p+=8;
	}
	int d=0,c=0;
	while(*p>' '){
		d=d*10+(*p++-'0');
		++c;
	}
	++p;
	if(c)x=x*ten<int>(c)+d;
	if(neg)x=-x;
}
template<class T,class U>
void sc(pair<T,U>&x){sc(x.fi),sc(x.se);}
template<int k=0,class T>
void sc_tup(T&x){
	if constexpr(k<tuple_size<T>::value){
		sc(get<k>(x));
		sc_tup<k+1>(x);
	}
}
template<class...T>
void sc(tuple<T...>&x){sc_tup(x);}
template<class T>
void sc(vc<T>&a){iter_mut(x,a)sc(x);}
template<class T>I&operator>>(T&x){sc(x);return *this;}
}i;
template<class...T>
void in(T&...x){(i.sc(x),...);}
struct O{
char b[N],*r=b+N,*p=b;
constexpr inline void flush(int need=N){
	if(r-p<need){
		fwrite(b,1,p-b,stdout);
		p=b;
	}
}
~O(){flush();}
void pr(char c){
	flush(1);
	*p++=c;
}
void pr(bool x){pr(x?'1':'0');}
void pr(const char*s){
	int n=strlen(s);
	for(int i=0;i<n;i++)pr(s[i]);
}
void pr(string s){for(char c:s)pr(c);}
void pr(double x){
	ostringstream os;
	os<<setprecision(18)<<x;
	pr(os.str());
}
void pr(long double x){pr((double)x);}
static constexpr auto num=[](){
	array<array<char,4>,10000>num={};
	for(int i=10000;i--;){
		int x=i;
		for(int j=4;j--;)num[i][j]=x%10|'0',x/=10;
	}
	return num;
}();
char tmp[20];
template<class T>
enable_if_t<is_integral_v<T>>pr(T x){
	flush(20);
	if(x<0)*p++='-',x=-x;
	int i;
	for(i=20;x>=10000;){
		i-=4;
		memcpy(tmp+i,&num[x%10000][0],4);
		x/=10000;
	}
	if(x>=1000)p=copy_n(&num[x][0],4,p);
	else if(x>=100)p=copy_n(&num[x][1],3,p);
	else if(x>=10)p=copy_n(&num[x][2],2,p);
	else *p++=x|'0';
	p=copy_n(tmp+i,20-i,p);
}
template<int k=16>
void w4(ll x){
	if constexpr(k==4){
		p=copy_n(&num[x][0],4,p);
		return;
	}else{
		p=copy_n(&num[x/ten<ll>(k-4)][0],4,p);
		w4<k-4>(x%ten<ll>(k-4));
	}
}
template<class T>
enable_if_t<is_128<T>>pr(T x){
	flush(40);
	if(x<0)*p++='-',x=-x;
	if(x<ten<T>(16))pr(static_cast<ll>(x));
	else if(x<ten<T>(32)){
		pr(static_cast<ll>(x/ten<T>(16)));
		w4(static_cast<ll>(x%ten<T>(16)));
	}else{
		pr(static_cast<int>(x/ten<T>(32)));
		x%=ten<T>(32);
		w4(static_cast<ll>(x/ten<T>(16)));
		w4(static_cast<ll>(x%ten<T>(16)));
	}
}
template<class T,class U>
void pr(pair<T,U>x){pr(x.fi),pr(' '),pr(x.se);}
template<int k=0,class T>
void pr_tup(T x){
	if constexpr(k<tuple_size<T>::value){
		if constexpr(k)pr(' ');
		pr(get<k>(x));
		pr_tup<k+1>(x);
	}
}
template<class...T>
void pr(tuple<T...>x){pr_tup(x);}
template<class T>
void pr(vc<T>a){
	int n=len(a);
	rep(i,n){
		if(i)pr(' ');
		pr(a[i]);
	}
}
template<class T>
void pr(const vvc<T>&a){
	int n=len(a);
	rep(i,n){
		if(i)pr('\n');
		pr(a[i]);
	}
}
template<class T,class U>
void pr(const vc<pair<T,U>>&a){
	int n=len(a);
	rep(i,n){
		if(i)pr('\n');
		pr(a[i]);
	}
}
template<class...T>
void pr(const vc<tuple<T...>>&a){
	int n=len(a);
	rep(i,n){
		if(i)pr('\n');
		pr(a[i]);
	}
}
template<class T>O&operator<<(T x){pr(x);return *this;}
}o;
void flush(){o.flush();}
void out(){o.pr('\n');}
template<char end='\n',char sep=' ',class T,class...Ts>
void out(T&&x,Ts&&...a){
	o.pr(x);
	((o.pr(sep),o.pr(a)),...);
	o.pr(end);
}
}
using io::in,io::out,io::flush;
#define cin io::i
#define cout io::o
#define INT(...)int __VA_ARGS__;in(__VA_ARGS__);
#define LL(...)ll __VA_ARGS__;in(__VA_ARGS__);
#define U32(...)u32 __VA_ARGS__;in(__VA_ARGS__);
#define U64(...)u64 __VA_ARGS__;in(__VA_ARGS__);
#define STR(...)string __VA_ARGS__;in(__VA_ARGS__);
#define CHR(...)char __VA_ARGS__;in(__VA_ARGS__);
#define DBL(...)double __VA_ARGS__;in(__VA_ARGS__);
#define I128(...)i128 __VA_ARGS__;in(__VA_ARGS__);
void decr(){}
template<class T,class...Ts>
void decr(T&x,Ts&...a){
	--x;
	decr(a...);
}
#define INT1(...)INT(__VA_ARGS__);decr(__VA_ARGS__);
#define LL1(...)LL(__VA_ARGS__);decr(__VA_ARGS__);
#define VEC(T,x,n)vc<T>x(n);in(x);
#define VV(T,x,h,w)vv(T,x,h,w);in(x);
#ifdef LOCAL
#define dbg(...)out(__VA_ARGS__)
#define SHOW(...)out('[',#__VA_ARGS__,"]:",__VA_ARGS__)
#else
#define dbg(...)
#define SHOW(...)
#endif
#define multicase INT(tt);while(tt--)
#define yesno(y,n)void y(bool f=1){out(f?#y:#n);}void n(bool f=1){y(!f);}
yesno(Yes,No)
template<class T>
struct coord_comp{
	vc<T>v;
	bool built=0;
	coord_comp(){}
	coord_comp(const vc<T>&a){init(a);}
	template<class A>void init(const A&a){
		int n=len(a);
		v.resize(n);
		rep(i,n)v[i]=a[i];
		built=0;
	}
	void add(T x){v.pb(x),built=0;}
	void build(){
		if(built)return;
		built=1;
		UNIQUE(v);
	}
	ll size(){build();return len(v);}
	template<bool strict=0>int operator()(T x){
		build();
		int i=LBI(v,x);
		if constexpr(strict)assert(0<=i&&i<len(v)&&v[i]==x);
		return i;
	}
	int lower_bound(T x){build();return LBI(v,x);}
	T operator[](int i){
		assert(0<=i&&i<size());
		return v[i];
	}
};
template<class T>
struct cumsum2d_dual{
	int n=0,m=0;
	vvc<T>d,s;
	bool built=0;
	cumsum2d_dual(){}
	cumsum2d_dual(int n,int m){init(n,m);}
	cumsum2d_dual(int n,int m,T x){init(n,m,x);}
	cumsum2d_dual(const vvc<T>&a){init(a);}
	template<class U>cumsum2d_dual(const vvc<U>&a){init(a);}
	template<class F>cumsum2d_dual(int n,int m,F f){init(n,m,f);}
	void init(int n,int m){
		this->n=n;
		this->m=m;
		d.assign(n,vc<T>(m));
		built=0;
	}
	void init(int n,int m,T x){
		init(n,m);
		if(n>0&&m>0)d[0][0]=x;
	}
	template<class U>void init(const vvc<U>&a){
		init(len(a),len(a[0]),[&](int i,int j){return a[i][j];});
	}
	template<class F>void init(int n,F f){
		init(n,m);
		rep(i,n)rep(j,m)d[i][j]=f(i,j);
		rep(i,n)rep(j,m-1)d[i][j+1]-=d[i][j];
		rep(i,n-1)rep(j,m)d[i+1][j]-=d[i][j];
	}
	void build(){
		if(built)return;
		built=1;
		s=d;
		rep(i,n)rep(j,m-1)s[i][j+1]+=s[i][j];
		rep(i,n-1)rep(j,m)s[i+1][j]+=s[i][j];
	}
	const vc<T>&operator[](int i){
		assert(0<=i&&i<n);
		build();
		return s[i];
	}
	T get(int i,int j){return (*this)[i][j];}
	const vvc<T>&get_all(){build();return s;}
	template<bool strict=1>
	void add(int i,int j,T v){
		if constexpr(strict)assert(0<=i&&i<=n&&0<=j&&j<=m);
		else chmax(i,0),chmax(j,0);
		if(i<n&&j<m)d[i][j]+=v,built=0;
	}
	template<bool strict=1>
	void add(int xl,int xr,int yl,int yr,T v){
		if constexpr(strict){
			assert(0<=xl&&xl<=xr&&xr<=n);
			assert(0<=yl&&yl<=yr&&yr<=m);
		}
		if(xr<=xl||xr<=0||n<=xl)return;
		if(yr<=yl||yr<=0||m<=yl)return;
		add(xl,yl,v);
		add(xl,yr,-v);
		add(xr,yl,-v);
		add(xr,yr,v);
	}
};
int main(){
	INT(n);
	vc<tuple<int,int,int,int>>p(n);
	cin>>p;
	coord_comp<int>comp_x,comp_y;
	iter(a,b,c,d,p){
		comp_x.add(a);
		comp_x.add(c);
		comp_y.add(b);
		comp_y.add(d);
	}
	int h=len(comp_x)-1,w=len(comp_y)-1;
	cumsum2d_dual<int>s(h,w);
	iter(a,b,c,d,p){
		a=comp_x(a);
		b=comp_y(b);
		c=comp_x(c);
		d=comp_y(d);
		s.add(a,c,b,d,1);
	}
	ll ans=0;
	rep(i,h)rep(j,w)if(s[i][j]){
		ans+=(comp_x[i+1]-comp_x[i])*ll(comp_y[j+1]-comp_y[j]);
	}
	out(ans);
}
accuracy: 1
time_ms: 100
memory_kb: 128364
final_rank: 8

code_snippet: // #include <atcoder/all>
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll inf = (1LL << 61);
ll dx[4] = {0, 1, 0, -1};
ll dy[4] = {-1, 0, 1, 0};
#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define REP(i, init, n) for (ll i = (ll)init; i < (ll)(n); ++i)
// ll op(ll a, ll b) { return min(a, b); }
// ll e() { return inf; }

auto comp(vector<int>& v1, vector<int>& v2) {
  vector<int> ret;
  ll n = v1.size();
  rep(i, n) {
    rep(j, 2) {
      ret.push_back(v1[i] + j);
      ret.push_back(v2[i] + j);
    }
  }
  sort(ret.begin(), ret.end());
  ret.erase(unique(ret.begin(), ret.end()), ret.end());
  rep(i, n) {
    v1[i] = lower_bound(ret.begin(), ret.end(), v1[i]) - ret.begin();
    v2[i] = lower_bound(ret.begin(), ret.end(), v2[i]) - ret.begin();
  }
  return ret;
}

int main() {
  ll n;
  cin >> n;
  vector<int> x1(n), x2(n), y1(n), y2(n);
  rep(i, n) cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
  auto vx = comp(x1, x2);
  auto vy = comp(y1, y2);
  ll X = vx.size(), Y = vy.size();
  vector<vector<int>> g(X + 1, vector<int>(Y + 1, 0));
  rep(i, n) {
    g[x1[i]][y1[i]]++;
    g[x1[i]][y2[i]]--;
    g[x2[i]][y1[i]]--;
    g[x2[i]][y2[i]]++;
  }
  rep(i, X) rep(j, Y + 1) g[i + 1][j] += g[i][j];
  rep(i, Y) rep(j, X + 1) g[j][i + 1] += g[j][i];
  ll ans = 0;
  rep(i, X - 1) {
    rep(j, Y - 1) {
      if (g[i][j] != 0) {
        ans += (ll)(vx[i + 1] - vx[i]) * (vy[j + 1] - vy[j]);
      }
    }
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 540
memory_kb: 253508
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

vector<long long> compress(vector<long long> &c1, vector<long long> &c2){
    vector<long long> res;
    int n = c1.size();
    for(int i = 0; i < n; i++){
        for(int j = 0; j < 2; j++){
            long long t1 = c1[i] + j;
            long long t2 = c2[i] + j;
            res.push_back(t1);
            res.push_back(t2);
        }
    }
    sort(res.begin(), res.end());
    res.erase(unique(res.begin(), res.end()), res.end());
    for(int i = 0; i < n; i++){
        c1[i] = lower_bound(res.begin(), res.end(), c1[i]) - res.begin();
        c2[i] = lower_bound(res.begin(), res.end(), c2[i]) - res.begin();
    }
    return res;
}

int main(){
    int n; cin>>n;
    vector<long long> x1(n), x2(n), y1(n), y2(n);
    for(int i = 0; i < n; i++){
        cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
    }
    
    vector<long long> x = compress(x1, x2);
    vector<long long> y = compress(y1, y2);
    
    int w = x.size();
    int h = y.size();
    
    vector<vector<int>> imos(w + 1, vector<int>(h + 1, 0));
    for(int i = 0; i < n; i++){
        imos[x1[i]][y1[i]]++;
        imos[x2[i]][y2[i]]++;
        imos[x1[i]][y2[i]]--;
        imos[x2[i]][y1[i]]--;
    }
    
    for(int i = 1; i < w; i++) for(int j = 0; j < h; j++) imos[i][j] += imos[i - 1][j];
    for(int i = 0; i < w; i++) for(int j = 1; j < h; j++) imos[i][j] += imos[i][j - 1];
    
    long long ans = 0;
    for(int i = 0; i < w - 1; i++) for(int j = 0; j < h - 1; j++){
        if(imos[i][j]) ans += (x[i + 1] - x[i]) * (y[j + 1] - y[j]);
    }
    cout << ans << endl;
    
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 253616
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

vector<long long> compress(vector<long long> &c1, vector<long long> &c2){
    vector<long long> res;
    int n = c1.size();
    for(int i = 0; i < n; i++){
        for(long long j = 0; j < 2; j++){
            long long t1 = c1[i] + j;
            long long t2 = c2[i] + j;
            res.push_back(t1);
            res.push_back(t2);
        }
    }
    sort(res.begin(), res.end());
    res.erase(unique(res.begin(), res.end()), res.end());
    for(int i = 0; i < n; i++){
        c1[i] = lower_bound(res.begin(), res.end(), c1[i]) - res.begin();
        c2[i] = lower_bound(res.begin(), res.end(), c2[i]) - res.begin();
    }
    return res;
}

int main(){
    int n; cin>>n;
    vector<long long> x1(n), y1(n), x2(n), y2(n);
    for(int i = 0; i < n; i++){
        cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
    }
    vector<long long> x = compress(x1, x2);
    vector<long long> y = compress(y1, y2);
    
    int w = x.size();
    int h = y.size();
    
    vector<vector<int>> imos(w, vector<int>(h, 0));
    for(int i = 0; i < n; i++){
        imos[x1[i]][y1[i]]++;
        imos[x1[i]][y2[i]]--;
        imos[x2[i]][y1[i]]--;
        imos[x2[i]][y2[i]]++;
    }
    
    for(int i = 1; i < w; i++) for(int j = 0; j < h; j++){
        imos[i][j] += imos[i - 1][j];
    }
    for(int i = 0; i < w; i++) for(int j = 1; j < h; j++){
        imos[i][j] += imos[i][j - 1];
    }
    
    long long ans = 0;
    
    for(int i = 0; i < w - 1; i++) for(int j = 0; j < h - 1; j++){
        if(imos[i][j]) ans += (x[i + 1] - x[i]) * (y[j + 1] - y[j]);
    }
    
    cout << ans << endl;
    
    return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 253624
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <typename T>
vector<T> compress(vector<T> &C1, vector<T> &C2) {
    vector<T> vals;
    int N = (int)C1.size();
    for (int i = 0; i < N; i++) {
        for (T d = 0; d <= 1; d++) {
            T tc1 = C1[i] + d;
            T tc2 = C2[i] + d;
            vals.push_back(tc1);
            vals.push_back(tc2);
        }
    }
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    for (int i = 0; i < N; i++) {
        C1[i] = lower_bound(vals.begin(), vals.end(), C1[i]) - vals.begin();
        C2[i] = lower_bound(vals.begin(), vals.end(), C2[i]) - vals.begin();
    }
    return vals;
}

int main(){
    int n; cin>>n;
    vector<long long> x1(n), y1(n), x2(n), y2(n);
    for(int i = 0; i < n; i++){
        cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
    }
    vector<long long> x = compress(x1, x2);
    vector<long long> y = compress(y1, y2);
    
    int w = x.size();
    int h = y.size();
    
    vector<vector<int>> imos(w, vector<int>(h, 0));
    for(int i = 0; i < n; i++){
        imos[x1[i]][y1[i]]++;
        imos[x1[i]][y2[i]]--;
        imos[x2[i]][y1[i]]--;
        imos[x2[i]][y2[i]]++;
    }
    
    for(int i = 1; i < w; i++) for(int j = 0; j < h; j++){
        imos[i][j] += imos[i - 1][j];
    }
    for(int i = 0; i < w; i++) for(int j = 1; j < h; j++){
        imos[i][j] += imos[i][j - 1];
    }
    
    long long ans = 0;
    
    for(int i = 0; i < w - 1; i++) for(int j = 0; j < h - 1; j++){
        if(imos[i][j]) ans += (x[i + 1] - x[i]) * (y[j + 1] - y[j]);
    }
    
    cout << ans << endl;
    
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 253616
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <typename T>
vector<T> compress(vector<T> &C1, vector<T> &C2) {
    vector<T> vals;
    int N = (int)C1.size();
    for (int i = 0; i < N; i++) {
        for (T d = 0; d <= 1; d++) {
            T tc1 = C1[i] + d;
            T tc2 = C2[i] + d;
            vals.push_back(tc1);
            vals.push_back(tc2);
        }
    }
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    for (int i = 0; i < N; i++) {
        C1[i] = lower_bound(vals.begin(), vals.end(), C1[i]) - vals.begin();
        C2[i] = lower_bound(vals.begin(), vals.end(), C2[i]) - vals.begin();
    }
    return vals;
}

int main(){
  int n; cin>>n;
  vector<long long> x1(n), x2(n), y1(n), y2(n);
  for(int i = 0; i < n; i++){
    cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
  }
  vector<long long> x = compress(x1, x2);
  vector<long long> y = compress(y1, y2);
 
  int w = (int)x.size();
  int h = (int)y.size();
  
  vector<vector<int>> imos(w, vector<int>(h, 0));

  for(int i = 0; i < n; i++){
    imos[x1[i]][y1[i]]++;
    imos[x1[i]][y2[i]]--;
    imos[x2[i]][y1[i]]--;
    imos[x2[i]][y2[i]]++;
  }

  for(int i = 1; i < w; i++) for(int j = 0; j < h; j++){
    imos[i][j] += imos[i - 1][j];
  }
  for(int i = 0; i < w; i++) for(int j = 1; j < h; j++){
    imos[i][j] += imos[i][j - 1];
  }
  
  long long ans = 0;
  for(int i = 0; i < w - 1; i++) for(int j = 0; j < h - 1; j++){
    if(imos[i][j]) ans += (x[i + 1] - x[i]) * (y[j + 1] - y[j]);
  }

  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 253512
final_rank: 12