题目描述

YLOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。

有一次,YLOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:

1、田地的形状是边平行于坐标轴的长方形;

2、左下角和右上角各有一个稻草人;

3、田地的内部(不包括边界)没有稻草人。

给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数

数据范围

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

=w=

给所有稻草人,按横坐标从小到大排序。

然后对横坐标进行分治,ans(l,r)=ans(l,mid)+ans(mid+1,r)+Ans

其中Ans表示,跨越x[mid](也就是中线)的答案数。


维护两个稻草人单调栈:

第一个维护的稻草人,横坐标递减。

第二个维护的稻草人,横坐标递增。

把区间内的稻草人,按纵坐标从大到小加入。

分情况讨论:

1.如果加入的是在中线之右的,那么把他加入第一个单调栈中。

2.如果加入的是在中线之左或之上的,那么把他加入第二个单调栈中;

紧接着,加入的这个稻草人,得出它在第二个单调栈中的上一个稻草人的纵坐标Y,那么在第一个单调栈中所有纵坐标在Y之下的,都可以与这个稻草人贡献一个答案。


提示:分治中可以套归并排序。

总的时间复杂度为O(nlog2n2):O(nlog2n)分治,O(log)归并排序。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define sqr(x) ((x)*(x))
#define ln(x,y) ll(log(x)/log(y))
using namespace std;
const char* fin="scarecrows.in";
const char* fout="scarecrows.out";
const ll inf=0x7fffffff;
const ll maxn=200007;
ll n,i,j,k,ans;
struct node{
ll x,y;
void operator =(const node &b){
x=b.x;
y=b.y;
}
}a[maxn],b[maxn];
bool cmp(node a,node b){
return a.x<b.x;
}
ll x[maxn];
ll st1[maxn],st2[maxn],num1,num2;
void push1(ll v){
while (num1 && a[v].x>a[st1[num1]].x) num1--;
st1[++num1]=v;
}
void push2(ll v){
while (num2 && a[v].x<a[st2[num2]].x) num2--;
st2[++num2]=v;
}
ll mergesort(ll l,ll r){
ll i,j,k,mid=(l+r)/2,Mid=x[mid];
if (l==r) return 0;
ll tmp=mergesort(l,mid)+mergesort(mid+1,r);
i=l;
j=mid+1;
k=l;
while (i<=mid && j<=r)
if (a[i].y>a[j].y) b[k++]=a[j++];
else b[k++]=a[i++];
while (i<=mid) b[k++]=a[i++];
while (j<=r) b[k++]=a[j++];
num1=num2=0;
for (i=r;i>=l;i--){
a[i]=b[i];
if (a[i].x<=Mid){
push1(i);
if (num1>1){
j=a[st1[num1-1]].y;
if (num2){
ll lef=1,rig=num2,mm;
while (lef<rig){
mm=(lef+rig)/2;
if (a[st2[mm]].y<=j) rig=mm;
else lef=mm+1;
}
if (a[st2[lef]].y<=j) tmp+=num2-lef+1;
}
}else tmp+=num2;
}else push2(i);
}
return tmp;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%lld",&n);
for (i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y),x[i]=a[i].x;
sort(x+1,x+n+1);
sort(a+1,a+n+1,cmp);
ans=mergesort(1,n);
printf("%lld",ans);
return 0;
}

=o=

一开始想的时候,其实也想到了:

把纵坐标从大到小加入;

计算所有稻草人作为左下角的贡献:
先想想对于一个稻草人a,如果要与另一个稻草人b贡献答案,存在什么样的条件:
1.b要比a更高,否则不满足a作为左下角的条件;
2.a,b构成的矩阵中不能有稻草人
在这里,先考虑满足其中某个条件,在对另一个条件进行讨论。
而“把纵坐标从大到小加入”正好达到了这个目的。

现在,只需要满足第二个条件就可以了。

第二个条件容易转化成“不存在一个稻草人在a的右上方,并且位于b的左下方”。
事实上,这个也是要满足多个条件。
1.a的右边
2.a的上边
3.b的下边
4.b的左边
所以我们考虑先满足其中的一个或几个。
我们考虑到可以使用分治,再维护两个单调栈来达成目的。

【JZOJ4925】【GDOI2017模拟12.18】稻草人的更多相关文章

  1. jzoj4918. 【GDOI2017模拟12.9】最近公共祖先 (树链剖分+线段树)

    题面 题解 首先,点变黑的过程是不可逆的,黑化了就再也洗不白了 其次,对于\(v\)的祖先\(rt\),\(rt\)能用来更新答案当且仅当\(sz_{rt}>sz_{x}\),其中\(sz\)表 ...

  2. jzoj4915. 【GDOI2017模拟12.9】最长不下降子序列 (数列)

    题面 题解 调了好几个小时啊--话说我考试的时候脑子里到底在想啥-- 首先,这个数列肯定是有循环节的,而且循环节的长度\(T\)不会超过\(D\) 那么就可以把数列分成三份,\(L+S+R\),其中\ ...

  3. jzoj4916. 【GDOI2017模拟12.9】完全背包问题 (背包+最短路)

    题面 题解 考场上蠢了--这么简单的东西都想不到-- 首先排序加去重. 先来考虑一下,形如 \[a_1x_1+a_2x_2+...a_nx_n=w,a_1<a_2<...<a_n,x ...

  4. 【GDOI2017模拟12.9】最近公共祖先

    题目 分析 首先,将这些节点按dfs序建一棵线段树. 因为按dfs序,所以在同一子树上的节点会放在线段树相邻的位置. 发现,对于一个位置x,它的权值只会对以x为根的子树造成影响. 当修改x时,用w[x ...

  5. [JZOJ4913] 【GDOI2017模拟12.3】告别

    题目 描述 题目大意 给你两个排列AAA和BBB,每次随即选三个数进行轮换操作,问mmm次操作内使AAA变成BBB的概率. 思考历程 首先随便搞一下,就变成了AAA中每个数回归自己原位. 一眼望去,感 ...

  6. 【JZOJ4930】【NOIP2017提高组模拟12.18】C

    题目描述 给出一个H的行和W列的网格.第i行第j列的状态是由一个字母的A[i][j]表示,如下: "." 此格为空. "o" 此格包含一个机器人. " ...

  7. 【JZOJ4929】【NOIP2017提高组模拟12.18】B

    题目描述 在两个n*m的网格上染色,每个网格中被染色的格子必须是一个四联通块(没有任何格子被染色也可以),四联通块是指所有染了色的格子可以通过网格的边联通,现在给出哪些格子在两个网格上都被染色了,保证 ...

  8. 【JZOJ4928】【NOIP2017提高组模拟12.18】A

    题目描述 数据范围 对于100%的数据,n<=100000,1<=A[i]<=5000 =w= Ans=∏1ai 代码 #include<iostream> #inclu ...

  9. Sprint3(12.18)总结

    Sprint3第三阶段 1.类名:软件工程-第三阶段 2.时间:至12.18 3.选题内容:web版-餐厅到店点餐系统 4.团队博客地址: http://www.cnblogs.com/queenju ...

随机推荐

  1. HZOI20190722 B visit 组合数+CRT合并

    题目:https://www.cnblogs.com/Juve/articles/11226266.html solution: 30%:dp 设dp[k][i][j]表示经过k时间,在(i,j)的方 ...

  2. LA3983 Robotruck

    虫洞 单调队列优化DP,感觉比较套路?上不去Vjudge,也懒得打就随便口胡一下.sxy大佬要是您看的我要是扯淡麻烦提醒我一下QAQ sum[i]表示从0到i依次走的距离,sg[i]表示1~i的重量和 ...

  3. uni-app中不使用scroll-view组件,监听页面滑直底部事件

    最终达到的目标效果 将要用到 监听页面滚动事件:onPageScroll 获取节点信息uni.createSelectorQuery() 标签布局 <template> <view ...

  4. 二叉查找树、平衡二叉树(AVL)、B+树、联合索引

    1. [定义] 二叉排序树(二拆查找树)中,左子树都比节点小,右子树都比节点大,递归定义. [性能] 二叉排序树的性能取决于二叉树的层数 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访 ...

  5. 《DSP using MATLAB》Problem 7.32

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  6. ORACLE忘记sys密码

    1.win+R打开dos窗口cmd 2.输入 sqlplus/nolog出现 3.输入 conn / as sysdba 出现 4.修改密码 alter user 用户 identified by 新 ...

  7. python-pygame安装教程

    网上有很多关于python,pygame的安装教程.大都比较麻烦,下面为大家介绍一种非常简单的安装方法.(因为安装大都是新手教程写详细一些) python是32位 python是3.6 1 pip配置 ...

  8. Luogu P4503 [CTSC2014]企鹅QQ(字符串哈希)

    P4503 [CTSC2014]企鹅QQ 题面 题目背景 \(PenguinQQ\) 是中国最大.最具影响力的 \(SNS(Social Networking Services)\) 网站,以实名制为 ...

  9. loj6402 校门外的树(dp,多项式求逆)

    https://loj.ac/problem/6402 庆祝一下,,,第一个我自己做出来的,,,多项式的题(没办法,我太弱 虽然用了2个小时才想出来,但这毕竟是0的突破…… 首先声明,虽然我写的题解很 ...

  10. 【solr】Solr5.5.4+Zookeeper3.4.6+Tomcat8搭建SolrCloud集群

    Solr5.5.4+Zookeeper3.4.6+Tomcat8搭建SolrCloud集群 SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力 ...