bzoj 4237: 稻草人 -- CDQ分治

Posted lkhll--qaz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4237: 稻草人 -- CDQ分治相关的知识,希望对你有一定的参考价值。

4237: 稻草人

Time Limit: 40 Sec  Memory Limit: 256 MB

Description

JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。
有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
田地的形状是边平行于坐标轴的长方形;
左下角和右上角各有一个稻草人;
田地的内部(不包括边界)没有稻草人。
给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数

 

Input

第一行一个正整数N,代表稻草人的个数
接下来N行,第i行(1<=i<=N)包含2个由空格分隔的整数Xi和Yi,表示第i个稻草人的坐标

 

Output

输出一行一个正整数,代表遵从启示的田地的个数

 

Sample Input

4
0 0
2 2
3 4
4 3

Sample Output

3

HINT

 

所有满足要求的田地由下图所示:

 技术分享图片

1<=N<=2*10^5

0<=Xi<=10^9(1<=i<=N)

0<=Yi<=10^9(1<=i<=N)

Xi(1<=i<=N)互不相同。

Yi(1<=i<=N)互不相同。

 
 

Source

 

先将x轴排序,然后CDQ分治,这样先保证左面x值一定小于右面

然后两边分别按y轴排序,然后去找合法解

我们可以左面维护x单调递增的栈,右面维护x单调递减的栈,这样对于左面的每一位在右面二分查找就好

#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 1000000007
#define ll long long
#define N 200010
inline int rd()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
int n;
ll ans;
struct qaz{int x,y;}a[N],b[N];
bool cmp(qaz a,qaz b){return a.x<b.x;}
int q1[N],q2[N];
int fd(int x,int l,int r)
{
    int mid;
    while(l+1<r)
    {
        mid=l+r>>1;
        if(a[q2[mid]].y<x) l=mid;
        else r=mid;
    }
    return l;
}
void cdq(int l,int r)
{
    if(l==r) return;
    int mid=l+r>>1;
    cdq(l,mid);cdq(mid+1,r);
    int i,j=l,t1=0,t2=0;
    for(i=mid+1;i<=r;i++)
    {
        while(t1&&a[q1[t1]].x>a[i].x) t1--;
        q1[++t1]=i;
        for(;j<=mid&&a[j].y<a[i].y;j++)
        {
            while(t2&&a[q2[t2]].x<a[j].x) t2--;
            q2[++t2]=j;
        }
        ans+=t2-fd(a[q1[t1-1]].y,0,t2+1); 
    }
    for(i=l,t1=l,t2=mid+1;i<=r;i++) b[i]=((t1<=mid&&a[t1].y<a[t2].y)||t2>r)?a[t1++]:a[t2++];
    for(i=l;i<=r;i++) a[i]=b[i];
}
int main()
{
    n=rd();
    for(int i=1;i<=n;i++) a[i].x=rd(),a[i].y=rd();
    sort(a+1,a+n+1,cmp);
    cdq(1,n);
    printf("%lld\n",ans);
    return 0;
}

 

以上是关于bzoj 4237: 稻草人 -- CDQ分治的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 4237 稻草人:CDQ分治+单调栈上二分

BZOJ4237: 稻草人

bzoj 4237 稻草人

[bzoj4237]稻草人

bzoj 4237 稻草人 CDQ

4237: 稻草人