[bzoj1935][Shoi2007]Tree 园丁的烦恼 _树状数组
Tree 园丁的烦恼 bzoj-1935 Shoi-2007
题目大意:给定平面上的$n$个点,$m$次查询矩形点个数。
注释:$1\le n,m\le 5\cdot 10^5$。
想法:静态二维数点。
$Orz Winniechen$,真tm敢写$KD-Tree$,虽然$T$了..
正常这种静态的二维数点我们都要请到树状数组。最简单的就是二维树状数组。
但是发现开不下,这样的话我们依据它可以离线这一点,我们将每个询问$(x1,y1)$到$(x2,y2)$变成$4$次查询:
$(x1-1,y1-1),(x1-1,y2),(x2,y1-1),(x2,y2)$把它们哥四个都当成点放入点集。每次都相当于查询$(1,1)$到$balabala$
每个点集中的点有$4$个参数:横纵坐标,种类和系数。
种类就是这个点到底是给定的点还是查询的点。
系数的话就是容斥前面的系数:$(x1-1,y1-1)$和$(x2,y2)$前面是$1$,$(x1-1,y2)$和$(x2,y1-1)$前面是$-1$。
然后我们将点集排序,横坐标递增为第一关键字,纵坐标递增为第二关键字。
紧接着我们顺次枚举每个点,如果这个点的种类是给定点,我们将它压到树状数组里。
是一个树状数组里,我们只开一个树状数组,记录的是小于每个横坐标的点的个数。
这样的话根据我们的关键字可知,每一个有可能更新查询的点都会被提前枚举过。
如果这个点是查询,就直接查询然后累加到对应查询的编号答案上,即可。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1000010
using namespace std;
struct Node
{
int x,y,f,id;//这里跟上述的有些不一样。
//我们用f直接可以同时记录种类和系数。如果f==0,那么就表示这个点是给定的点,反之f=1或-1代表系数,直接累计即可。
}q[N<<2];
int tree[10000010];
int mx=0;
int ans[N];
inline bool cmp(const Node &a,const Node &b)
{
return a.x!=b.x?a.x<b.x:(a.y!=b.y?a.y<b.y:a.id<b.id);
}
int a,b,c,d;
int cnt;
inline int lowbit(int x) {return x&(-x);}
void fix(int x)
{
// if(!x) x++;
// puts("fix");
for(int i=x;i<=mx+1;i+=lowbit(i))
{
// printf("aha %d\n",i);
tree[i]++;
}
}
int query(int x)
{
// puts("query");
int ans=0;
for(int i=x;i>=1;i-=lowbit(i))
{
ans+=tree[i];
}
return ans;
}
int main()
{
int n,m; cin >> n >> m ;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&q[i].x,&q[i].y);
q[i].x++,q[i].y++;
mx=max(mx,q[i].y);
}
cnt=n;
// puts("Fuck 1");
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
c++,d++;
q[++cnt].x=c; q[cnt].y=d; q[cnt].f=1; q[cnt].id=i;//这里不要把系数搞错
q[++cnt].x=c; q[cnt].y=b; q[cnt].f=-1; q[cnt].id=i;
q[++cnt].x=a; q[cnt].y=d; q[cnt].f=-1; q[cnt].id=i;
q[++cnt].x=a; q[cnt].y=b; q[cnt].f=1; q[cnt].id=i;
}
// printf("Gun %d\n",cnt);
// puts("Fuck 2");
sort(q+1,q+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
{
// printf("Shit %d\n",i);
if(!q[i].id) fix(q[i].y);
else ans[q[i].id]+=query(q[i].y)*q[i].f;//这就是直接压到一个变量的好处,不用特判直接加就行了,反正如果是给定点f就是0,不会影响答案。
}
// puts("Fuck 3");
for(int i=1;i<=m;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}
小结:这个想法极其常用,很多静态可离线二维数点问题都可以用这个来解决。那些动态的就让KD-Tree上吧,反正出了那种题被卡常的不可能只有你一个人/手动滑稽
[bzoj1935][Shoi2007]Tree 园丁的烦恼 _树状数组的更多相关文章
- [BZOJ1935][SHOI2007]Tree 园丁的烦恼(树状数组)
题目描述 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草. 有一天国王漫步在花园里,若有所思,他问一个园丁道: “最近我在思 ...
- [bzoj1935][shoi2007]Tree 园丁的烦恼(树状数组+离线)
1935: [Shoi2007]Tree 园丁的烦恼 Time Limit: 15 Sec Memory Limit: 357 MBSubmit: 980 Solved: 450[Submit][ ...
- BZOJ1935: [Shoi2007]Tree 园丁的烦恼
1935: [Shoi2007]Tree 园丁的烦恼 Time Limit: 15 Sec Memory Limit: 357 MBSubmit: 552 Solved: 220[Submit][ ...
- bzoj千题计划143:bzoj1935: [Shoi2007]Tree 园丁的烦恼
http://www.lydsy.com/JudgeOnline/problem.php?id=1935 二维偏序问题 排序x,离散化树状数组维护y #include<cstdio> #i ...
- BZOJ1935: [Shoi2007]Tree 园丁的烦恼(树状数组 二维数点)
题意 题目链接 Sol 二维数点板子题 首先把询问拆成四个矩形 然后离散化+树状数组统计就可以了 // luogu-judger-enable-o2 #include<bits/stdc++.h ...
- [BZOJ1935][SHOI2007]Tree 园丁的烦恼(离线+树状数组)
题意 给出第一象限的n个点,有m次询问,每次询问一个矩形中的点的个数.(0<=n,m<=500000,0<=xi,yi<=10000000) 题解 一眼望去不可做. 用二位前缀 ...
- 初涉二维数点问题&&bzoj1935: [Shoi2007]Tree 园丁的烦恼
离线好评 Description 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他问一个 ...
- 【树状数组】bzoj1935 [Shoi2007]Tree 园丁的烦恼
把y坐标离散化后,按x坐标排序,把询问拆成四个点,每次询问某个点左下角的点的个数,注意处理边界和重叠的情况. #include<cstdio> #include<algorithm& ...
- [bzoj4822][Cqoi2017]老C的任务&[bzoj1935][Shoi2007]Tree 园丁的烦恼
来自FallDream的博客,未经允许,请勿转载,谢谢. 老 C 是个程序员. 最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统.作为经验丰富的程序员,老 C 轻松地完成 ...
随机推荐
- ie8 js编译器对象为空或不是对象的一个小问题
昨天在遍历json串的时候碰到了如下图所示的问题,除ie8以下版本的浏览器运行都是正常的, 部分代码如下: 1 var Workmodel=function(){ 2 model_json=[ 3 { ...
- 9.10NOIP模拟题
9.10 NOIP模拟赛 题目名称 区间 种类 风见幽香 题目类型 传统 传统 传统 可执行文件名 section kinds yuuka 输入文件名 section.in kinds.in yu ...
- P4407 [JSOI2009]电子字典
传送门 我的哈希打挂了--然而大佬似乎用哈希可以过还跑得很快-- 删除,枚举删哪个字符,记删之后的哈希值存map 插入,相当于在单词里删字符,去对应的map里查找 更改,相当于两个都删掉同一个位置的字 ...
- SpringBoot2.0整合Redission
Redisson是redis一个很强大的客户端,有兴趣的同学可以看我的下一篇文章,这篇主要讲如何整合,费话不多说,直接上干货(大牛请绕道) 首先创建RedissionConfig文件 import o ...
- ACM_尿裤子
Problem Description: 小X上课的时候喝了一大壶水,午饭后他极限跑回宿舍上厕所,结果发现不知道哪个逗比舍友在宿舍门上加了一把4位密码锁,然后还留了纸条:密码是6666,小X只能一个一 ...
- c++ 四种类型转换机制
类型转换机制可以分为:隐式类型转换 和 显示类型转换(强制类型转换) C中的类型转换: 事情要从头说起,这个头就是C语言.我们已经习惯了使用C-like类型转换,因为它强大而且简单. 主要有一下两种形 ...
- Elasticsearch之CURL命令的bulk批量操作
大家,也可去看看我下面的博客 Elasticsearch之批量操作bulk 官网上,是举例了新建一个requests文件. [hadoop@master elasticsearch-]$ pwd /h ...
- [ SCOI 2005 ] 最大子矩阵
\(\\\) \(Description\) 给出一个\(N\times M\)的有权矩阵,选出其中\(K\)个互不重叠的子矩阵,使得这\(K\)个子矩阵的权值和最大. \(N\in [1,100]\ ...
- Java&Xml教程(三)使用DOM方式修改XML文件内容
DOM解析方式也可用于修改XML数据,我们可以使用它完成新增元素.删除元素.修改元素值.修改元素属性等操作. 我们的XML文件,内容如下: employee.xml <?xml version= ...
- Android FrameWork 学习之Android 系统源码调试
这是很久以前访问掘金的时候 无意间看到的一个关于Android的文章,作者更细心,分阶段的将学习步骤记录在自己博客中,我觉得很有用,想作为分享同时也是留下自己知识的一些欠缺收藏起来,今后做项目的时候会 ...