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) ...
随机推荐
- bzoj千题计划188:bzoj1923: [Sdoi2010]外星千足虫 (高斯—若尔当消元法解异或方程组)
http://www.lydsy.com/JudgeOnline/problem.php?id=1923 #include<cstdio> #include<cstring> ...
- [转载]五理由 .NET开发者应该关注HTML 5
http://developer.51cto.com/art/201107/275039.htm
- linux的lemon安装示范
\(First\): 1. 准备好 lemon原文件 2. 解压压缩包(名字必须是lemon) 第二步:找到readme.md这个文件 第三步:了解一下安装指南 第四步:打开终端 注意:源代码目录就是 ...
- 查询总结、HQL语法、QBC(QueryByCriteria)深入学习
1.查询总结 在之前的批量查询练习的时候练习基本五种查询方法的使用: 1.OID查询---根据对象ID进行查询 2.对象属性导航查询: obj.getXXX 3.HQL查询:Query对象查询 4.Q ...
- rap 部署
Rap 安装 war包下载地址 https://github.com/thx/RAP/releases 创建数据库,并创建权限用户 mysql> create database rap_db c ...
- mysqlbinlog 查看mysql bin 日志 mysqlbinlog: unknown variable 'default-character-set=utf8'
mysqlbinlog mysql-bin.000036 | less 查询包含几个字段的语句: mysqlbinlog mysql-bin.000036| egrep '(201103061000 ...
- 用一句SQL查询相对复杂的统计报表
--统计从2017年3月份开始每个月金融服务支付前分期申请数以及通过(核账完成)数 ,ApplyTime)) ,ApplyTime)) as varchar)+'月' as 日期,count(*) a ...
- Java 连接远程Linux 服务器执行 shell 脚本查看 CPU、内存、硬盘信息
pom.xml jar 包支持 <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch& ...
- Java中final关键字概述
使用final修饰过的变量都不可以改变: 1.final修饰变量 恒定不变的属性,可以用final关键字来修饰: 变量名建议全部使用大写 final修饰的变量不能改变,如果程序中重新赋值,编译报错 例 ...
- High-Speed Tracking with Kernelized Correlation Filters
2015年的一篇论文,可参考:http://blog.csdn.net/carrierlxksuper/article/details/46461245. 另参考:http:// ...