POJ 2464 Brownie Points II(树状数组)
一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要O(n^2),结果发现自己想多了。。。
其实是每个点画根竖线和横线就好,对于相同竖线统计(一直不包含线上点)右上左下总点数的最小值,最后不同竖线求一个最大值。对于每条等于这个最小值最大化的竖线都找一个右下与左上的最大值,排序输出即可。注意这儿排序后需要去重
思想倒是不难,主要就是麻烦。只需要分别离散化x轴,y轴的点,然后枚举每个点找到四个方向的其他总点数,这儿用树状数组可以简单解决。但是注意空间问题不能开二维,开一维排序x轴,再左右扫一遍,一边计算一边添加点即可,注意x y轴线上的点要减去。先扫一边找到最小值最大化的值与每条竖线包含哪些点,再扫一遍找到等于那个值的竖线中的最大右下左上和
代码写得很麻烦
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Max=;
int bit[Max];
struct node
{
int xx1,yy1;
int lup,rup,ldo,rdo;
} poi[Max];
int n;
bool cmp1(struct node p1,struct node p2)
{
if(p1.xx1==p2.xx1)
return p1.yy1<p2.yy1;
return p1.xx1<p2.xx1;
}
bool cmp2(struct node p1,struct node p2)
{
return p1.yy1<p2.yy1;
}
int lowbit(int x)
{
return x&(-x);
}
void Add(int y)
{
while(y<=n)
{
bit[y]++;
y+=lowbit(y);
}
return;
}
int Sum(int y)
{
if(!y)
return ;
int sum=;
while(y>)
{
sum+=bit[y];
y-=lowbit(y);
}
return sum;
}
void Dtz()//离散化
{
sort(poi,poi+n,cmp2);
int m=;
poi[n].yy1=Inf;
for(int i=; i<n; i++)
{
if(poi[i].yy1!=poi[i+].yy1)//注意不能和前一个进行比较,因为前一个已经被赋值
poi[i].yy1 = m++;
else
poi[i].yy1 = m;
} sort(poi,poi+n,cmp1);
m=;
poi[n].xx1=Inf;
for(int i=; i<n; i++)
{
if(poi[i].xx1!=poi[i+].xx1)
poi[i].xx1 = m++;
else
poi[i].xx1 = m;
}
return ;
}
int tem[Max],minx[Max],pos[Max];
void Solve()
{
int sum;
memset(bit,,sizeof(bit));
for(int i=; i<n; i++) //边添加边查询
{
if(i!=&&poi[i].xx1==poi[i-].xx1)
sum++;
else
sum=;
poi[i].ldo=Sum(poi[i].yy1-)-sum;//减一,避免y轴相同的点被计算
poi[i].lup=Sum(n)-Sum(poi[i].yy1);
Add(poi[i].yy1);
} memset(bit,,sizeof(bit));
for(int i=n-; i>=; i--)
{
if(i!=n-&&poi[i].xx1==poi[i+].xx1)
sum++;
else
sum=;
poi[i].rdo=Sum(poi[i].yy1-);
poi[i].rup=Sum(n)-Sum(poi[i].yy1)-sum;
Add(poi[i].yy1);
} int manx=,mans;//统计
int coun=,cnt=;
minx[]=Inf;
for(int i=; i<n; i++)//计算最小值最大的是多少
{
if(!i||poi[i].xx1==poi[i-].xx1)
{
if(poi[i].rup+poi[i].ldo<minx[coun])
minx[coun]=poi[i].rup+poi[i].ldo;
}
else
{
manx=max(manx,minx[coun]);
pos[coun++]=i;//每条同x轴的最后一个的后一个下标
minx[coun]=Inf;
if(poi[i].rup+poi[i].ldo<minx[coun])
minx[coun]=poi[i].rup+poi[i].ldo;
}
}
pos[coun]=n;
manx=max(manx,minx[coun]); for(int i=;i<=coun;i++)
{
if(minx[i]==manx)//此x轴可用
{
mans=;
for(int j=i==?:pos[i-];j<pos[i];j++)
mans=max(mans,poi[j].lup+poi[j].rdo);
tem[cnt++]=mans;
}
} printf("Stan: %d; Ollie:",manx);
sort(tem,tem+cnt);
int cntt=;
for(int i=;i<cnt;i++)//去重
if(tem[i]!=tem[cntt])
tem[++cntt]=tem[i];
for(int i=; i<=cntt; i++)
printf(" %d",tem[i]);
printf(";\n");
return ;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
for(int i=; i<n; i++)
scanf("%d %d",&poi[i].xx1,&poi[i].yy1);
Dtz();//离散化
Solve();
}
return ;
}
POJ 2464 Brownie Points II(树状数组)的更多相关文章
- POJ 2464 Brownie Points II --树状数组
题意: 有点迷.有一些点,Stan先选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画一条横线.Stan选这两条直线分成的左下和右上部分的点,Ollie选左上和右下部分的点.Sta ...
- hdu 1156 && poj 2464 Brownie Points II (BIT)
2464 -- Brownie Points II Problem - 1156 hdu分类线段树的题.题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通 ...
- POJ 2464 Brownie Points II (树状数组,难题)
题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...
- POJ - 2464 Brownie Points II 【树状数组 + 离散化】【好题】
题目链接 http://poj.org/problem?id=2464 题意 在一个二维坐标系上 给出一些点 Stan 先画一条过一点的水平线 Odd 再画一条 过Stan那条水平线上的任一点的垂直线 ...
- UVA 10869 - Brownie Points II(树阵)
UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分 ...
- POJ 2155 Matrix(二维树状数组,绝对具体)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20599 Accepted: 7673 Descripti ...
- poj 3321:Apple Tree(树状数组,提高题)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18623 Accepted: 5629 Descr ...
- POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树
题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...
- poj 3321 Apple Tree(一维树状数组)
题目:http://poj.org/problem?id=3321 题意: 苹果树上n个分叉,Q是询问,C是改变状态.... 开始的处理比较难,参考了一下大神的思路,构图成邻接表 并 用DFS编号 白 ...
随机推荐
- 在Debian上用Bind 配置DNS服务器
1 什么是DNS 初学者可能不理解DNS到底是什么,干什么用.我是在1998年大学毕业时才听说这个词的.那时我在聊天室碰到潍坊信息港的一个网管,我恬不知耻地说我也是个网管,他说也维护DNS吗?我说,D ...
- MySQL 获得当前日期时间\时间戳 函数 ( 转自传智播客)
MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now(); +-------+ | now() | +-- ...
- IOS - 内购
内购的五种产品类别 •非消耗品(Nonconsumable)买了就有,头衔,功能 –指的是在游戏中一次性购买并拥有永久访问权的物品或服务.非消耗品物品可以被用户再次下载,并且能够在用户的所有设备上使用 ...
- AFNetworking request failed unacceptable content type text/html
今天体验AFNetwork 3.1.0 进行数据解析,但是解析数据控制台一直都输出这样的 error 结果: 于是,照着以前AFN2.+版本的进行设置: 结果发现在新版本的 AFN 上不能设置了.既然 ...
- [Android] 查看Android中的AlarmManager事件
reference to : https://segmentfault.com/a/1190000000404684 有时候我们需要设置一个alarmmanager事件 但是如果这个事件的时间是凌晨三 ...
- cmd for备忘
=============参数 /d (参数只能显示当前目录下的目录名字)=================== rem 显示d:\work\目录下与*.txt相匹配的文件(如果报错就%i-> ...
- python基础——访问限制
python基础——访问限制 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还 ...
- linux rpm问题:怎样查看rpm安装包的安装路径
x rpm问题:怎样查看rpm安装包的安装路径 2010-07-12 21:19:15 标签:rpm linux 路径 休闲 职场 rpm -qpl xxxxxx.rpm 1.如何安装rpm软件包 ...
- python基础语法(二)
本文主要包括以下内容 函数 切片 迭代 列表生成式 生成器 迭代器 函数 定义函数 定义函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块 ...
- hdu 1711Number Sequence
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 数字KMP,原来还能这么用 #include<stdio.h> ],b[]; ]; ...