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; }