HDU 5091---Beam Cannon(线段树+扫描线)
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5091
To simplify the problem, the Beam Cannon can shot at any area in the space, and the attack area is rectangular. The rectangle parallels to the coordinate axes and cannot rotate. It can only move horizontally or vertically. The enemy spaceship in the space can be considered as a point projected to the attack plane. If the point is in the rectangular attack area of the Beam Cannon(including border), the spaceship will be destroyed.
A test case starting with a negative integer terminates the input and this test case should not to be processed.
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=1e4+;
int n,w,h;
struct Node
{
int x,y,v;
}node[*N];
struct TNode
{
int f;
int m;
}tr[*N]; bool cmp(const Node s1,const Node s2)
{
if(s1.x==s2.x) return s1.v>s2.v;
return s1.x<s2.x;
}
void build(int l,int r,int i)
{
tr[i].f=; tr[i].m=;
if(l==r) return ;
int mid=(l+r)>>;
build(l,mid,i<<);
build(mid+,r,i<<|);
}
void pushdown(int i)
{
tr[i<<].f+=tr[i].f;
tr[i<<|].f+=tr[i].f;
tr[i<<].m+=tr[i].f;
tr[i<<|].m+=tr[i].f;
tr[i].f=;
}
void update(int l,int r,int i,int t)
{
if(l>=node[t].y&&r<=node[t].y+h)
{
tr[i].f+=node[t].v;
tr[i].m+=node[t].v;
return ;
}
if(tr[i].f!=) pushdown(i);
int mid=(l+r)>>;
if(node[t].y<=mid) update(l,mid,i<<,t);
if(node[t].y+h>mid) update(mid+,r,(i<<|),t);
tr[i].m=max(tr[i<<].m,tr[i<<|].m);
}
int main()
{
while(scanf("%d",&n)&&n>)
{
scanf("%d%d",&w,&h);
for(int i=;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
node[*i-].x=x;
node[*i-].y=y+*N;
node[*i-].v=;
node[*i].x=x+w;
node[*i].y=y+*N;
node[*i].v=-;
}
sort(node+,node+*n+,cmp);
build(,*N,);
int sum=;
for(int i=;i<=*n;i++)
{
update(,*N,,i);
sum=max(sum,tr[].m);
}
printf("%d\n",sum);
}
return ;
}
补充一下:HDU 4007 和这题相似(2016 ICPC大连站热身赛)
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=4007
题意:给了n个点,求一个正方形能围住的最大点数,同样正方形平行于坐标轴;
思路:与上面的题一样,但是这题数据范围很大,线段树的数组开不了这么大,那么必须要进行离散化;
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
typedef long long LL;
LL L,R;
map<LL,LL>p;
struct Node
{
LL x,y;
LL v;
}node[];
struct TNode
{
LL m;
LL f;
}tr[];
bool cmp1(const Node s1,const Node s2)
{
if(s1.x==s2.x) return s1.v>s2.v;
return s1.x<s2.x;
}
bool cmp2(const Node s1,const Node s2)
{
return s1.y<s2.y;
}
void build(LL l,LL r,LL i)
{
tr[i].m=;
tr[i].f=;
if(l==r) return ;
LL mid=(l+r)>>;
build(l,mid,i<<);
build(mid+,r,i<<|);
}
void pushdown(LL i)
{
tr[i<<].f+=tr[i].f;
tr[i<<|].f+=tr[i].f;
tr[i<<].m+=tr[i].f;
tr[i<<|].m+=tr[i].f;
tr[i].f=;
}
void update(LL l,LL r,LL i,LL t)
{
if(l>=L&&r<=R){
tr[i].f+=t;
tr[i].m+=t;
return ;
}
pushdown(i);
LL mid=(l+r)>>;
if(L<=mid) update(l,mid,i<<,t);
if(R>mid) update(mid+,r,i<<|,t);
tr[i].m=max(tr[i<<].m,tr[i<<|].m);
}
int main()
{
LL n,r;
while(scanf("%lld%lld",&n,&r)!=EOF)
{
p.clear();
for(LL i=;i<=n;i++)
{
LL x,y;
scanf("%lld%lld",&x,&y);
node[*i-].x=x;
node[*i-].y=y;
node[*i-].v=;
node[*i-].x=x+r;
node[*i-].y=y;
node[*i-].v=-;
node[*i].x=x;
node[*i].y=y+r;
node[*i].v=;
}
sort(node+,node+*n+,cmp2);
///离散化
LL tot=,pre=-;
for(LL i=;i<=*n;i++)
{
if(node[i].y!=pre){
pre=node[i].y;
p[pre]=++tot;
}
}
sort(node+,node+*n+,cmp1);
build(,tot,);
LL sum=;
for(LL i=;i<=*n;i++)
{
if(node[i].v==) continue;
L=p[node[i].y];
R=p[node[i].y+r];
update(,tot,,node[i].v);
sum=max(sum,tr[].m);
}
printf("%lld\n",sum);
}
return ;
}
HDU 5091---Beam Cannon(线段树+扫描线)的更多相关文章
- [POI 2001+2014acm上海邀请赛]Gold Mine/Beam Cannon 线段树+扫描线
Description Byteman, one of the most deserving employee of The Goldmine of Byteland, is about to re ...
- hdu 5091 Beam Cannon(扫描线段树)
题目链接:hdu 5091 Beam Cannon 题目大意:给定N个点,如今要有一个W∗H的矩形,问说最多能圈住多少个点. 解题思路:线段的扫描线,如果有点(x,y),那么(x,y)~(x+W,y+ ...
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- HDU 6096 String 排序 + 线段树 + 扫描线
String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...
- HDU 5091 Beam Cannon (扫描线思想)
题意:移动一个矩形,使矩形内包含的点尽量多. 思路:把一个点拆成两个事件,一个进(权值为1)一个出(权值为-1),将所有点按照x排序,然后扫描,对于每个x,用一个滑窗计算一下最大值,再移动扫描线.树状 ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu 5091 Beam Cannon
题目大意: 有n个点(n<=10000),点的坐标绝对值不超过20000,然后问你用一个w*h(1<=w,h<=40000)的矩形,矩形的边平行于坐标轴,最多能盖住多少个点. 刘汝佳 ...
- HDU 3265 Posters ——(线段树+扫描线)
第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: #include <stdio.h> #include <algorithm> ...
- 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
随机推荐
- C#设计模式-简单工厂
工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类.工厂模式有以下几种形态: 简单工厂(Simple Factory)模式 工厂方法(F ...
- js获取当前时间显示在页面上
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- unity生成WP工程后ExtendedSplashImage显示不正确的问题
这个bug我已经彻底无语了,居然这么久都没有fix. 解决方法如下: <SwapChainPanel x:Name="DXSwapChainPanel"> <Gr ...
- easyuidatagrid中load,reload,loadData的区别。
摘要:datagrid中有load,reload,loadData那三个方式,皆是加载数据的,但又有差别.下面让我们一起来看看: 首先,load方法,比如我已经定义一个datagrid的id为grid ...
- 美团(iPad)顶部界面的简单实现, 及开发时常见bug
项目功能介绍:1.支持横竖屏旋转,界面正常显示2.通过点击界面顶部"美团",可展示出左右双tableView分别显示服务类列表和子类列表3.通过点击界面顶部"广州&quo ...
- KendoUI系列:AutoComplete
1.基本使用 <link href="@Url.Content("~/C ontent/kendo/2014.1.318/kendo.common.min.css" ...
- CardLayout布局练习(小的图片浏览器)
/* 涉及Panel中的图片的加载,还有Frame的关闭的方法, CardLayout(int hgap, int vgap)就会决定卡片面板的大小 匿名类的使用... */ import java. ...
- Cocos2d-x 3.2 学习笔记(十五)保卫萝卜 场景与数据
保卫萝卜~场景的思路以及数据的存储. 学习要写笔记,记录自己的步骤. 一.场景构建Tiled 关于Tiled网上有一大堆的教程,这个比较好用,特别是构建塔防类的游戏极其简 ...
- 拓扑排序(二)之 C++详解
本章是通过C++实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处:http://www.cnblogs. ...
- WTF Forms – 使用 CSS 实现用户体验更好的表单
WTF forms 借助 CSS 提供友好的 HTML 表单控件,专为 IE9+ 以及最新的 Chrome.Safari 和 Firefox 浏览器.以文件输入控件的改进,使用 label 包裹在 i ...