bzoj4237

cdq分治+单调栈+二分

对y分治,单调栈上部维护递增,下部递减,因为一旦一个点不满足单调性了,就会把前面的点卡掉,所以在单调栈里干掉那些点

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010;
struct data {
    int x, y;
} a[N], b[N];
int n;
ll ans;
int st1[N], st2[N];
int find(int v, int l, int r)
{
    while(r - l > 1)
    {
        int mid = (l + r) >> 1;
        if(a[st2[mid]].x >= v) r = mid;
        else l = mid;
    }
    return l;
}
bool cpx(data A, data B)
{
    return A.x == B.x ? A.y < B.y : A.x < B.x;
}
bool cpy(data A, data B)
{
    return A.y < B.y;
}
void cdq(int l, int r)
{
    if(l >= r) return;
    int mid = (l + r) >> 1;
    cdq(l, mid);
    cdq(mid + 1, r);
    int j = l, top1 = 0, top2 = 0;
    for(int i = mid + 1; i <= r; ++i) 
    {
        while(top1 && a[i].y < a[st1[top1]].y) --top1;
        st1[++top1] = i;
        for(; a[j].x < a[i].x && j <= mid; ++j)
        {
            while(top2 && a[j].y > a[st2[top2]].y) --top2;
            st2[++top2] = j;
        }
        ans += top2 - find(a[st1[top1 - 1]].x, 0, top2 + 1);
    }
    sort(a + l, a + r + 1, cpx);
} 
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d%d", &a[i].x, &a[i].y);
    sort(a + 1, a + n + 1, cpy);
    cdq(1, n);
    printf("%lld\n", ans);
    return 0;
}
View Code

 

posted @ 2017-07-18 10:57  19992147  阅读(150)  评论(0编辑  收藏  举报