bzoj4237

题解:

cdq分治

二位变成一维

二分一下

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200011;
int n,Stack[N],top,Stack2[N],tail;
LL ans;
struct node{int x,y;}a[N];
bool cmpx(node q,node qq){return q.x<qq.x;}
bool cmpy(node q,node qq){return q.y<qq.y;}
void solve(int l,int r)
{
    if (l==r) return;
    sort(a+l,a+r+1,cmpy);
    int mid=(l+r)>>1;
    sort(a+l,a+mid+1,cmpx);
    sort(a+mid+1,a+r+1,cmpx);
    top=tail=0;
    int now=l,L,R,pos,mm,cp;
    for (int i=mid+1;i<=r;i++)
     {
        while (top>0&&a[Stack[top]].y>=a[i].y)top--;
        Stack[++top]=i;
        while (now<=mid&&a[now].x<a[i].x)
         {
            while (tail>0&&a[Stack2[tail]].y<=a[now].y) tail--;
            Stack2[++tail]=now;
            now++;
         }
        L=1;R=tail;pos=-1;cp=a[Stack[top-1]].x;
        while (L<=R)
         {
            mm=(L+R)>>1;
            if (a[Stack2[mm]].x>cp) pos=mm,R=mm-1;
            else L=mm+1;
         }
        if (pos!=-1) ans+=tail-pos+1;
     }
    solve(l,mid);
    solve(mid+1,r);
}
int main()
{
    scanf("%d",&n); 
    for (int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
    a[0].x=a[0].y=-1;
    solve(1,n);
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8652810.html