一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要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(树状数组)的更多相关文章

  1. POJ 2464 Brownie Points II --树状数组

    题意: 有点迷.有一些点,Stan先选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画一条横线.Stan选这两条直线分成的左下和右上部分的点,Ollie选左上和右下部分的点.Sta ...

  2. hdu 1156 && poj 2464 Brownie Points II (BIT)

    2464 -- Brownie Points II Problem - 1156 hdu分类线段树的题.题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通 ...

  3. POJ 2464 Brownie Points II (树状数组,难题)

    题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...

  4. POJ - 2464 Brownie Points II 【树状数组 + 离散化】【好题】

    题目链接 http://poj.org/problem?id=2464 题意 在一个二维坐标系上 给出一些点 Stan 先画一条过一点的水平线 Odd 再画一条 过Stan那条水平线上的任一点的垂直线 ...

  5. UVA 10869 - Brownie Points II(树阵)

    UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分 ...

  6. POJ 2155 Matrix(二维树状数组,绝对具体)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20599   Accepted: 7673 Descripti ...

  7. poj 3321:Apple Tree(树状数组,提高题)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Descr ...

  8. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  9. poj 3321 Apple Tree(一维树状数组)

    题目:http://poj.org/problem?id=3321 题意: 苹果树上n个分叉,Q是询问,C是改变状态.... 开始的处理比较难,参考了一下大神的思路,构图成邻接表 并 用DFS编号 白 ...

随机推荐

  1. jQueryUI Datepicker的使用

    jQueryUI Datepicker是一个高度可定制的插件,可以很方便的为你的页面添加日期选择功能,你可以自定义日期的显示格式 以及要使用的语言. 你可以使用键盘的快捷键来驱动datepicker插 ...

  2. iOS应用架构谈(三):网络层设计方案(上)

    iOS客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来讨论iOS应用架构中的种种问题,本文是其中的第三篇,主要讲网络层设计以及安全机制和优化方案. 前言 网络层在一个Ap ...

  3. 剑指Offer——网易笔试之解救小易

    知识要点 首先介绍一下曼哈顿,曼哈顿是一个极为繁华的街区,高楼林立,街道纵横,从A地点到达B地点没有直线路径,必须绕道,而且至少要经C地点,走AC和 CB才能到达,由于街道很规则,ACB就像一个直角3 ...

  4. JavaScript基础——数据类型

    JavaScript使用数据类型来确定如何处理被分配给一个变量的数据.变量的类型决定了你可以对变量进行什么操作,如循环或者执行.下面描述了最常用的变量类型. 字符串(String):此数据类型将字符数 ...

  5. Lattice Diamond 的学习之新建工程

    1).打开软件 在软件打开后的初始布局会有一个Start  page 可以创建.打开.导入一个ISPLEVER 工程. 2).建立工程:1,Start page 中Project --> NEW ...

  6. yum -y list java* 查看当前java的版本

    [root@NB ok]# yum -y list java* Loaded plugins: fastestmirror, refresh-packagekit, security Loading ...

  7. CLR via C#(16)--泛型

    泛型就像是一个模板,常常定义一些通用的算法,具体调用时再替换成实际的数据类型,提高了代码的可重用性. 一.初识泛型 1. 简单实例 以最常用的FCL中的泛型List<T >为例: stat ...

  8. 【转载】有哪些省时小技巧,是每个Linux用户都应该知道的

    http://www.cnblogs.com/amberly/p/4352682.html

  9. SVM 最大间隔目标优化函数(NG课件2)

        目标是优化几何边距, 通过函数边距来表示需要限制||w|| = 1     还是优化几何边距,St去掉||w||=1限制转为普通函数边距     更进一步的,可以固定函数边距为1,调节||w| ...

  10. Delphi中的基础数据类型

    参考http://www.cnblogs.com/del/archive/2007/12/04/982167.html 在学习之初,在这么多的数据类型中,最好记住这五种标准数据类型(整型.实型.字符型 ...