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;
}
时间: 2024-10-13 06:10:59

bzoj 4237: 稻草人 -- CDQ分治的相关文章

BZOJ 4237: 稻草人

4237: 稻草人 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 661  Solved: 286[Submit][Status][Discuss] Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: 田地的形状是边平行于坐标轴的长方形: 左下角和右上角各有一个稻草人: 田地的内部(不

bzoj4237: 稻草人 cdq分治 单调栈

目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分的贡献 对当前两区间x排序后,对上部分维护单增单调栈,得到距离当前点最近的比她低的点p 对于下面的区间维护一个上凸壳 ,直接在凸壳上二分p统计答案 代码 #include<set> #include<cstdio> #include<cstring> #include<

BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]

Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值. 以下N行,每

BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包

题意:链接 方法:cdq分治或平衡树维护凸包 解析: 这道题我拒绝写平衡树的题解,我仅仅想说splay不要写挂,insert边界条件不要忘.del点的时候不要脑抽d错.有想写平衡树的去看140142或者留言我. 首先这道题能推出个表达式 f[i]代表第i天最大收益. xx[i]表示将第i天的钱都买A的数量 yy[i]表示将第i天的钱都买B的数量 所以f[i]=max(f[i?1],p[i].a?xx[j]+p[i].b?yy[j])j<i 所以我们要维护这个n^2的递推式 又知道f[i]是由小于

BZOJ 2141: 排队 CDQ分治+bit

2141: 排队 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观.设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量.幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度.为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序

BZOJ 3262: 陌上花开 cdq分治 树状数组

https://www.lydsy.com/JudgeOnline/problem.php?id=3262 cdq分治板子题,一维排序,一维分治(cdq里的队列),一维数据结构(树状数组). 学dp优化前来复习--以前好像写过这道题但是没写博客啊--在校oj上写的题都没怎么写博客,追悔莫及 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #

[bzoj] 1176 Mokia || CDQ分治

原题 给出W×W的矩阵(S没有用,题目有误),给出无限次操作,每次操作的含义为: 输入1:你需要把(x,y)(第x行第y列)的格子权值增加a 输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出 输入3:表示输入结束 因为修改之间相互独立,所以可以用CDQ. 三个维度分别为时间,x轴,y轴. 简单的三维偏序即可. #include<cstdio> #include<algorithm> #define N 100010 #define

bzoj 3262: 陌上花开 -- CDQ分治

3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MB Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,00

BZOJ 1176 Balkan 2007 Mokia CDQ分治

题目大意:有一些操作,给一个坐标代表的点加上一个数,和求出一个矩形中的所有数的和. 思路:一眼题,二位树状数组水过. ... .. . 哪里不对?W<=2000000.逗我?这n^2能开下? 这个时候CDQ神牛又来帮助我们了. 这个题应该算是CDQ分治的模板题了吧,简单分析一下,其实不难. 写这个题之前建议写一下BZOJ 1935 SHOI 2007 Tree 园丁的烦恼 树状数组这个题,是本题的简化版. 按照正常的解法,我们应该建立一个二位的数据结构,然后分别维护两维的信息.如果用动态开点的线