bzoj 1818 主席树

思路:主席树搞一搞。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg
using namespace std;
 
const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;
 
int hs1[N], hs2[N], mnX[N], mxX[N], mnY[N], mxY[N], tot1, tot2, n;
int root[2][N];
 
struct Point {
    int x, y;
    Point(int _x = 0, int _y = 0) {
        x = _x; y = _y;
    }
} a[N];
 
struct Chairman_tree {
    int tot;
    struct node {
        int sum, l, r;
    } a[N * 20];
    void update(int p, int l, int r, int &x, int y) {
        x = ++tot; a[x] = a[y]; a[x].sum++;
        if(l == r) return;
        int mid = l + r >> 1;
        if(p <= mid) update(p, l, mid, a[x].l, a[y].l);
        else update(p, mid + 1, r, a[x].r, a[y].r);
    }
    int query(int L, int R, int l, int r, int x, int y) {
        if(L > R) return 0;
        if(l >= L && r <= R) return a[x].sum - a[y].sum;
        int mid = l + r >> 1, ans = 0;
        if(L <= mid) ans += query(L, R, l, mid, a[x].l, a[y].l);
        if(R > mid) ans += query(L, R, mid + 1, r, a[x].r, a[y].r);
        return ans;
    }
} ct[2];
 
int main() {
    ct[0].tot = ct[1].tot = 0;
    memset(mnX, inf, sizeof(mnX));
    memset(mnY, inf, sizeof(mnY));
    memset(mxX, 0, sizeof(mxX));
    memset(mxY, 0, sizeof(mxY));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].x, &a[i].y);
        hs1[++tot1] = a[i].x;
        hs2[++tot2] = a[i].y;
    }
    sort(hs1 + 1, hs1 + 1 + tot1);
    sort(hs2 + 1, hs2 + 1 + tot2);
    tot1 = unique(hs1 + 1, hs1 + 1 + tot1) - hs1 - 1;
    tot2 = unique(hs2 + 1, hs2 + 1 + tot2) - hs2 - 1;
 
    for(int i = 1; i <= n; i++) {
        a[i].x = lower_bound(hs1 + 1, hs1 + 1 + tot1, a[i].x) - hs1;
        a[i].y = lower_bound(hs2 + 1, hs2 + 1 + tot2, a[i].y) - hs2;
        mnX[a[i].x] = min(mnX[a[i].x], a[i].y);
        mxX[a[i].x] = max(mxX[a[i].x], a[i].y);
        mnY[a[i].y] = min(mnY[a[i].y], a[i].x);
        mxY[a[i].y] = max(mxY[a[i].y], a[i].x);
    }
 
    for(int i = 1; i <= tot2; i++) {
        ct[0].update(mnY[i], 1, tot1, root[0][i], root[0][i - 1]);
        ct[1].update(mxY[i], 1, tot1, root[1][i], root[1][i - 1]);
    }
 
    LL ans = 0;
 
    for(int i = 1; i <= tot1; i++) {
        ans += mxX[i] - mnX[i] + 1;
        ans -= ct[0].query(i + 1, tot1, 1, tot1, root[0][mxX[i]], root[0][mnX[i]-1]);
        ans -= ct[1].query(1, i - 1, 1, tot1, root[1][mxX[i]], root[1][mnX[i]-1]);
    }
 
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9622980.html