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编号 白 ...
随机推荐
- Django~Views
In Django, web pages and other content are delivered by views. To get from a URL to a view, Django u ...
- [Android]drawable-nodpi文件夹 的作用
把一些不能被拉伸的图片放在 drawable-nodpi 中,此图片将不会被放大,以原大小显示. 看下图: 这两个图片被放到了drawable-nodpi 中 在不同分辨率下的显示大小是一样的,不会被 ...
- codeforces 500A. New Year Transportation
题目链接:http://codeforces.com/problemset/problem/500/A 题目意思:给出 n-1 个 cell,每个 cell 有一个值 ai,表示在这个编号为 i 的 ...
- BestCoder22 1003.NPY and shot 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5144 题目意思:有个人抛物体,已知抛的速度和高度,问可以抛到的最远距离是多少.即水平距离. 做的时候是 ...
- js注册读秒进度条
转载自://http://blog.csdn.net/wugouzi/article/details/12621385 <head> <meta http-equiv="C ...
- 【leetcode】Sort List (middle)
Sort a linked list in O(n log n) time using constant space complexity. 思路: 用归并排序.设输入链表为S,则先将其拆分为前半部分 ...
- Keepalived虚拟ip
linux下如何设置vip(虚拟ip) 在做HA的时候需要为服务器设计虚拟IP,也就是一个主机对应多个IP地址?刚听起来好神奇,原来这样也是可能的看了下面的这个链接 自己配了一下http://hi.b ...
- hadoop 2.5 hdfs namenode –format 出错Usage: java NameNode [-backup] |
在 cd /home/hadoop/hadoop-2.5.2/bin 下 执行的./hdfs namenode -format 报错[hadoop@node1 bin]$ ./hdfs nameno ...
- 20145206邹京儒《Java程序设计》第一周学习总结
20145206 <Java程序设计>第1周学习总结 教材学习内容总结 1.三大平台:Java SE.Java EE与Java ME.Java SE是各应用平台的基础,分为四个主要的部分: ...
- sql中union和union all的用法
如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字.union(或称为联合)的作用是将多个结果合并在一起显示出来. union和unio ...