bzoj4237 稻草人

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)互不相同。

正解:$CDQ$分治。

感觉做法很神奇,自己根本就想不到啊。。

我们考虑如何使用分治计算答案,按照$y$坐标分治,对于上半部分和下半部分分别按照$x$坐标排序。我们枚举上半区间的每个点作为右上角的点来统计答案。

考虑一下上半区间一定能堵住当前点的点,一定是它之前被处理的点中$y$坐标比它小且$x$坐标最大的点,那么这个点我们可以用单调栈求出,所以对于上半区间,我们维护一个$y$坐标递增的单调栈。同样,对于下半区间,我们考虑怎样的点可以被计入答案,在当前点加入以后,那么$x$坐标和$y$坐标都比它小的点绝对不可能被计入答案,于是我们对下半区间维护一个$y$坐标单调递减的单调栈。同时我们在单调栈内二分,只有当下半区间中的点的$x$坐标大于上半区间单调栈中倒数第二个点的$x$坐标,这个点才是对于上半区间当前点合法的答案。

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set>
13 #define inf (1<<30)
14 #define N (500010)
15 #define il inline
16 #define RG register
17 #define ll long long
18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
19
20 using namespace std;
21
22 struct data{ int x,y; }q[N],qu[N];
23
24 int st1[N],st2[N],hsh[N],n,tot;
25 ll ans;
26
27 il int gi(){
28     RG int x=0,q=1; RG char ch=getchar();
29     while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar();
30     if (ch==‘-‘) q=-1,ch=getchar();
31     while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar();
32     return q*x;
33 }
34
35 il int cmpx(const data &a,const data &b){ return a.x<b.x; }
36
37 il int cmpy(const data &a,const data &b){ return a.y<b.y; }
38
39 il void solve(RG int l,RG int r){
40     if (l==r) return; RG int mid=(l+r)>>1,t1=l-1,t2=mid;
41     for (RG int i=l;i<=r;++i) if (q[i].y<=mid) qu[++t1]=q[i]; else qu[++t2]=q[i];
42     for (RG int i=l;i<=r;++i) q[i]=qu[i]; RG int top1=0,top2=0,L,R,Mid,res;
43     for (RG int i=mid+1,j=l;i<=r;++i){
44     while (top1 && q[st1[top1]].y>=q[i].y) --top1; st1[++top1]=i;
45     for (;j<=mid && q[j].x<q[i].x;++j){
46         while (top2 && q[st2[top2]].y<=q[j].y) --top2; st2[++top2]=j;
47     }
48     L=1,R=top2,res=top2+1;
49     while (L<=R){
50         Mid=(L+R)>>1;
51         if (q[st2[Mid]].x>=q[st1[top1-1]].x) res=Mid,R=Mid-1;
52         else L=Mid+1;
53     }
54     ans+=top2-res+1;
55     }
56     solve(l,mid),solve(mid+1,r); return;
57 }
58
59 il void work(){
60     n=gi(),q[0].x=q[0].y=-1;
61     for (RG int i=1;i<=n;++i) q[i].x=gi(),q[i].y=gi(),hsh[++tot]=q[i].y;
62     sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1;
63     for (RG int i=1;i<=n;++i) q[i].y=lower_bound(hsh+1,hsh+tot+1,q[i].y)-hsh;
64     sort(q+1,q+n+1,cmpx),solve(1,n),printf("%lld\n",ans); return;
65 }
66
67 int main(){
68     File("scarecrow");
69     work();
70     return 0;
71 }
时间: 2024-10-17 07:59:07

bzoj4237 稻草人的相关文章

bzoj4237: 稻草人 cdq分治 单调栈

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

bzoj4237稻草人

题意:给你一个田地,问左下角和右上角有稻草人并且内部除了边界都没有稻草人的矩形数. 标程: 1 #include<bits/stdc++.h> 2 using namespace std; 3 int read() 4 { 5 int x=0,f=1;char ch=getchar(); 6 while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} 7 while (ch>='0'&&ch<='9'

bzoj4237 稻草人——分治

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4237 分治: 先把所有点按 y 排序,然后二分递归: 对于每个 mid ,计算经过它的矩形的个数,把上面的每个点当做右上角,考虑下面多少点可以作为左下角: 上面的限制只有前面的 y 大于等于自己的 y,所以维护递增的单调栈: 下面的限制是后面的 y 小于等于自己的 y,所以维护递减的单调栈: 还要注意 x 的限制,二分找到栈内满足条件的最前面的点,到栈顶的元素个数就是对答案的贡献. 代码如

NOIWC2018游记

NOIWC2018游记 接着PKUWC就是NOIWC了.感觉时间很紧呀,但越是紧张呢,就越让人心里觉得充实. 能够去NOIWC,应该是一次非常充实的体验吧. 这一篇游记是接着上一篇写的,时间点上完全都能够接起来.这是一个传送门 PKUWC2018游记 by租酥雨 如果没有什么不可抗因素阻碍的话应该能够保证日更吧... 记得当初PKUWC赛程公布的时候,SYC很惊讶地问我: 为什么不上课呀? 真是个好问题. 那么NOIWC有课上了萝卜他一定会很开心吧(雾 大致地看了一下课程安排:线段树?概率期望?

《巨婴国》:差评。伪科学/非科学,逻辑比较差,以偏概全,解释牵强,竖起一个稻草人打得挺嗨。1星

读后感觉比较差.只能给1星.相当于负分的水平. 作者认为中国人大部分是没长大的婴儿,不能正确处理人际关系,隐含地推论常见的心理疾病.变态人格.不正常情商都是巨婴病的表现,明确地推论巨婴理论可以解释许多世界历史和国际政治上的事情. 差评理由有下面几个: 1:“巨婴国”的学说到底是不是一个严肃的学术上的推论?我认为不是.我认为可以归入伪科学或非科学的范畴.作者虽然是北大心理学系的本科和硕士毕业,但是全书是浓郁的江湖派的风格.作者提到了一个惊世骇俗的“巨婴学说”,并且断定中国人大部分是“巨婴”,因此中

时代的稻草人

叶圣陶老先生写过一篇童话<稻草人>:稻草人"骨架子是竹园里的细竹枝,肌肉.皮肤是隔年的黄稻草,拿着一把破扇子".稻草人尽职尽责.心地善良,但面对现实却无能为力.他爱他的主人,却不能赶走田里的害虫给主人带来好收成,他帮不了生病的孩子.频死的鲫鱼和寻死的女人--许知远的<时代的稻草人>引用了这个童话,并表达了知识分子在这个时代面前深深的无力感. <稻草人>写于1922年,正值五四运动后新思想与旧观念的激烈冲突之时,"在历史的惯性与现实面前,新思

BZOJ 4237: 稻草人

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

HDU4462稻草人

l问题描述:有一块N*N的玉米田(N<=50),给定K个(X,Y)的坐标位置(K<=10)和相应的覆盖范围,请问,至少在这K个位置中选择几个放置稻草人,能保证玉米田全被覆盖? 1 #include<stdio.h> 2 #include<cstring> 3 #include<iostream> 4 5 using namespace std; 6 7 int field[52][52]; 8 int N,K; 9 10 struct Node{ 11 in

bzoj 4237: 稻草人 -- CDQ分治

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