Educational Codeforces Round 68 E. Count The Rectangles

Educational Codeforces Round 68 E. Count The Rectangles

Portal

Meaning of the questions:

Is given not more than \ (n, n \ leq 5000 \) straight lines, the total number of Q is formed rectangular.

Ideas:

Considering the \ (n-\) small range, it is possible to enumerate two parallel lines of violence, that is the number of straight line perpendicular to the next process.
Into two intersecting rectangles satisfying the condition, if we enumerate straight line perpendicular to the \ (X \) axis, the two conditions is the \ (low \ leq y_i \ leq high, x_ {i, 0} \ leq left, right \ I Leq X_ {,}. 1 \) .
So we can consider the idea of scanning lines, the use of weights Fenwick tree maintenance in accordance with its right and left end, select Insert / Remove a straight line, insert the time \ (y_i \) value. After the two straight lines to the vertical, the scope of the query \ (Low \) ~ (High \) \ horizontal distance between a line number to. Set it as \ (the X-\) , then the contribution of the answer to is \ (the X-C_ {} ^ 2 \) .
Note \ (low \) may be larger than \ (high \) situation.
code show as below:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 50005;
int n;
int x[N][2], y[N][2];
int X[N], Y[N];
struct seg1{
    int x, y1, y2;
    bool operator < (const seg1 &A) const {
        return x < A.x;
    }
}s1[N];
struct seg2{
    int y, x1, x2;
}s2[N];
vector <int> v1[N], v2[N], v3[N];
int c[N];
int lowbit(int x) {
    return x & (-x);
}
void add(int x, int v) {
    for(int i = x; i < N; i += lowbit(i)) c[i] += v;
}
int query(int p) {
    int ans = 0;
    for(int i = p; i; i -= lowbit(i)) ans += c[i];
    return ans;
}
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    int D1 = 0, D2 = 0;
    for(int i = 1; i <= n; i++) {
        cin >> x[i][0] >> y[i][0] >> x[i][1] >> y[i][1];
        X[++D1] = x[i][0]; X[++D1] = x[i][1];
        Y[++D2] = y[i][0]; Y[++D2] = y[i][1];
    }
    sort(X + 1, X + D1 + 1); sort(Y + 1, Y + D2 + 1);
    D1 = unique(X + 1, X + D1 + 1) - X - 1;
    D2 = unique(Y + 1, Y + D2 + 1) - Y - 1;
    int t1 = 0, t2 = 0;
    for(int i = 1; i <= n; i++) {
        x[i][0] = lower_bound(X + 1, X + D1 + 1, x[i][0]) - X;
        x[i][1] = lower_bound(X + 1, X + D1 + 1, x[i][1]) - X;
        y[i][0] = lower_bound(Y + 1, Y + D2 + 1, y[i][0]) - Y;
        y[i][1] = lower_bound(Y + 1, Y + D2 + 1, y[i][1]) - Y;
        if(x[i][0] > x[i][1]) swap(x[i][0], x[i][1]);
        if(y[i][0] > y[i][1]) swap(y[i][0], y[i][1]);
        if(x[i][0] == x[i][1]) s1[++t1] = seg1{x[i][0], y[i][0], y[i][1]};
        if(y[i][0] == y[i][1]) s2[++t2] = seg2{y[i][0], x[i][0], x[i][1]};
        if(y[i][0] == y[i][1]) v1[x[i][0]].push_back(t2);
    }
    sort(s1 + 1, s1 + t1 + 1);
    for(int i = 1; i <= t1; i++) v3[s1[i].x].push_back(i);
    ll res = 0;
    int bound = D1;
    for(int x = 1; x <= bound; x++) {
        for(auto it : v2[x]) {
            add(s2[it].y, -1);
        }
        for(auto it : v1[x]) {
            add(s2[it].y, 1);
            v2[s2[it].x2].push_back(it);
        }
        for(auto i : v3[x]) {
            for(int j = x + 1; j <= bound; j++) {
                for(auto k : v3[j]) {
                    int R = min(s1[i].y2, s1[k].y2), L = max(s1[i].y1, s1[k].y1);
                    if(L > R) continue;
                    int tmp = query(R) - query(L - 1);
                    res += 1ll * tmp * (tmp - 1) / 2;
                }
                for(auto it : v2[j]) add(s2[it].y, -1);
            }
            for(int j = x + 1; j <= bound; j++) {
                for(auto it : v2[j]) add(s2[it].y, 1);
            }
        }
    }
    cout << res;
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/11299408.html
Recommended