Bzoj4237 cdq分治+树状数组+单调栈
二维平面在某区域内点的问题,要么树套树,kdtree,要么就是cdq分治了。
然而这题树套树和kdtree都不是很好搞的样子,于是我们就只能cdq分治了。
首先把点按照横坐标x排序,在每一层我们需要算出右边的点和左边的点组成的点对的贡献。
我们先把这些点按照纵坐标降序排列。
考虑我们按照纵坐标从大到小扫描到的每一个点。
如果他是右边的点,需要横坐标比他上面的点大才能直接加入,否则他会挡住其右上方的点,使其无法成为答案。
于是单调栈维护一下就好了。
对于左边的点,他能构成答案的纵坐标区间,一定要在他本身纵坐标以上且其右上方的点的最低纵坐标以下才行。
所以这个,我们可以用树状数组以横坐标x为下标维护纵坐标y的后缀min(什么你说树状数组只能维护前缀?后缀坐标转化为n-x[i]+1不就成前缀了?)。
然后就是查询,由于我懒得考虑二分的细节了,所以又用另外一个树状数组维护右面的点在纵坐标y上的区间和。
详见下面的图。
注意这题保证横纵坐标没有重复,所以对拍写maker的时候注意不要出重复坐标,否则网上的代码谁跟谁跑的都不一样,别问我怎么知道的。
然后给一组数据:
5
3 1
1 3
2 5
4 2
5 4
答案是4。
最后上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lli long long int
using namespace std;
const int maxn=2e5+1e2;
const int inf=0x3f3f3f3f; struct Node {
int x,y;
friend bool operator < (const Node &a,const Node &b) {
return a.x < b.x;
}
}ns[maxn]; int x[maxn],y[maxn];
int id[maxn],stk[maxn],top;
int n;
lli ans; struct BinaryIndexTreeA {
int dat[maxn];
#define lowbit(x) (x&-x)
BinaryIndexTreeA() { memset(dat,0x3f,sizeof(dat)); }
inline void update(int pos,int x) {
while( pos <= n ) dat[pos] = min( dat[pos] , x ) , pos += lowbit(pos);
}
inline int query(int pos) {
int ret = inf;
while( pos ) ret = min( ret , dat[pos] ) , pos -= lowbit(pos);
return ret;
}
inline void reset(int pos) {
while( pos <= n ) dat[pos] = inf , pos += lowbit(pos);
}
}bx;
struct BinaryIndexTreeB {
lli dat[maxn];
#define lowbit(x) (x&-x)
inline void update(int pos,int x) {
while( pos <= n ) dat[pos] += x , pos += lowbit(pos);
}
inline lli query(int pos) {
lli ret = ;
while( pos ) ret += dat[pos], pos -= lowbit(pos);
return ret;
}
inline void reset(int pos) {
while( pos <= n ) dat[pos] = , pos += lowbit(pos);
}
}by; inline bool cmp(int a,int b) {
return y[a] < y[b];
}
inline void solve(int l,int r) {
if( l == r ) return;
const int mid = ( l + r ) >> ;
for(int i=l;i<=r;i++) id[i] = i;
sort(id+l,id+r+,cmp);
top = ;
for(int i=r;i>=l;i--) {
const int p = id[i];
if( p > mid ) {
while( top && x[stk[top]] > x[p] ) by.update(y[stk[top--]],-);
stk[++top] = p;
by.update(y[p],);
} else {
int mxy = bx.query(n-x[p]+);
mxy = min( mxy , n );
ans += by.query(mxy) - by.query(y[p]-);
bx.update(n-x[p]+,y[p]);
}
}
for(int i=r;i>=l;i--) {
const int p = id[i];
if( p > mid ) by.reset(y[p]);
else bx.reset(n-x[p]+);
}
solve(l,mid);
solve(mid+,r);
} inline void refac(int* sou) {
static int srt[maxn],len;
memcpy(srt+,sou+,sizeof(int)*n);
sort(srt+,srt++n);
len = unique(srt+,srt++n) - srt - ;
for(int i=;i<=n;i++) sou[i] = lower_bound(srt+,srt++len,sou[i]) - srt;
}
inline void ncpy(int ope) {
if( ope == ) {
for(int i=;i<=n;i++)
ns[i].x = x[i] , ns[i].y = y[i];
} else if( !~ope ) {
for(int i=;i<=n;i++)
x[i] = ns[i].x , y[i] = ns[i].y;
}
} int main() {
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d%d",x+i,y+i); refac(x) , refac(y);
ncpy() , sort(ns+,ns++n) , ncpy(-);
solve(,n); printf("%lld\n",ans); return ;
}
Bzoj4237 cdq分治+树状数组+单调栈的更多相关文章
- BZOJ4237 稻草人(分治+树状数组+单调栈)
如果要询问的某个纵坐标为inf的点左边是否有点能与其构成所要求的矩形,只要用个单调栈就可以了.可以想到用分治来制造单调性. 按横坐标排序,每次考虑跨过分治中心的矩形.考虑右边的每个点能与左边的哪些点构 ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- BZOJ 1176 Mokia CDQ分治+树状数组
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
- 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组
题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...
- BZOJ 2683 简单题 cdq分治+树状数组
题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...
- LOJ3146 APIO2019路灯(cdq分治+树状数组)
每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...
- BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组
考虑答案的构成,发现是一个有限制条件的偏序问题. 然后三个维度的DP,可以排序.CDQ.树状数组各解决一维. #include <map> #include <cmath> # ...
- HDU 4247 Pinball Game 3D(cdq 分治+树状数组+动态规划)
Pinball Game 3D Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- IE条件注释判断
相信大家都知道IE有专门的注释条件判断来引入一些css.js.html代码,但是语法有点拗口,记不住,下面我来做一下笔记: 正常的html注释: <!--注释注释注释注释...--> 注释 ...
- 20181111 Quartz(慕课网)
Quartz体系结构 三个核心概念 调度器 任务 触发器 重要组成 Job JobBuilder JobDetail JobStore Trigger TriggerBuilder ThreadPoo ...
- Web性能优化系列(3):如何延迟加载JS
本文由 伯乐在线 - J.c 翻译,sunbiaobiao 校稿.未经许可,禁止转载!英文出处:www.feedthebot.com.欢迎加入翻译小组. 延迟加载JavaScript JavaScri ...
- Javascript摸拟自由落体与上抛运动 说明!
JavaScript 代码 //**************************************** //名称:Javascript摸拟自由落体与上抛运动! //作者:Gloot //邮箱 ...
- [机器学习&数据挖掘]SVM---软间隔最大化
根据上个硬间隔最大化已经知道,在解决线性可分数据集的分类问题时,求得拉格朗日乘子.w.b就得到分离超平面,然后就可以进行分类,软间隔最大化是针对非线性可分的数据集,因为并不是数据集在可分的时候会出现一 ...
- Ajax和jsonp区别
大多数情况下,无论是框架还是自己实现都是通过Ajax的方式来向后端请求数据的,而Ajax之间是通过传输json格式的文件来进行数据的传输的,大家对Ajax也很熟悉了,那么为什么我又要使用jsonp呢? ...
- 转载 你不知道的super
http://funhacks.net/2016/11/09/super/ super仅被用于新式类 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能 ...
- 洛谷 P5206: bzoj 5475: LOJ 2983: [WC2019] 数树
一道技巧性非常强的计数题,历年WC出得最好(同时可能是比较简单)的题目之一. 题目传送门:洛谷P5206. 题意简述: 给定 \(n, y\). 一张图有 \(|V| = n\) 个点.对于两棵树 \ ...
- RabbitMQ集群使用Haproxy负载均衡
(1).下载 http://www.haproxy.org/#down (2).解压 tar -zxvf haproxy-1.5.18.tar.gz (3).安装 1).编译 make TARGET= ...
- Python查找算法之 -- 列表查找和二分查找
一.列表查找:从列表中查找指定元素 输入:列表.待查找元素 输出:元素下标或未查找到元素 二.列表查找方式 顺序查找 : 从列表的第一个元素开始遍历,知道找到为止.时间复杂度O(n) 二分查找 :从有 ...