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) ...
随机推荐
- Python内置函数之匿名(lambda)函数
Python内置函数之匿名(lambda)函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.匿名函数 #!/usr/bin/env python #_*_coding:utf ...
- hdu 5181 numbers
http://acm.hdu.edu.cn/showproblem.php?pid=5181 题意: 有一个栈,其中有n个数1~n按顺序依次进入栈顶,在某个时刻弹出. 其中m个限制,形如数字A必须在数 ...
- python解析minicap
上篇知道了minicap发送图片的格式,照着官网的app.js代码,改用一个python版的来解析它,适当扩展,可以做个小工具实时显示手机屏幕. 步骤: 一.手机开启minicap服务 adb she ...
- 面积并+扫描线 覆盖的面积 HDU - 1255
题目链接:https://cn.vjudge.net/problem/HDU-1255 题目大意:中文题目 具体思路:和上一篇的博客思路差不多,上一个题求的是面积,然后我们这个地方求的是啊覆盖两次及两 ...
- linux下查看各硬件型号
查看主板型号 # dmidecode |grep -A 8 "System Information"System Information 上网查DELL CS24-TY,找到说主板 ...
- mac lsof使用查看端口
安装 brew install lsof 在Mac OS系统中,无法使用netstat来查看端口占用情况,可以使用lsof来代替,这种方式在Linux下也适用. sudo lsof -nP -iTCP ...
- IE WebBrowser内核设置
public class IEVersion { /// <summary> /// IE WebBrowser内核设置 /// </summary> public stati ...
- poj2148
题意:给出若干个没有公共面积的多边形,几个多边形可能属于同一个国家,要求给这个地图染色,同一个国家用相同的颜色,相邻国家不能用相同颜色.问最少需要多少种颜色. 分析:计算几何+搜索.先判断哪些多边形是 ...
- java 完全解耦
只要有一个方法操作的是类而非接口,那么你就只能使用这个类及其子类,如果你想要将这个方法应用于不在此继承结构中的某个类,那么你就会触霉头,接口可以在很大程度上放宽这种限制,因此,我们可以编写可服用性更好 ...
- FileOutputSteam入门
FileOutputSteam 字节输入流 从控制台将字节保存到本地硬盘 package com.isoftstone.io; import java.io.FileOutputStream; imp ...