Stan and Ollie play the game of Odd Brownie Points. Some brownie points are located in the plane, at integer coordinates. Stan plays first and places a vertical line in the plane. The line must go through a brownie point and may cross many (with the same x-coordinate). Then Ollie places a horizontal line that must cross a brownie point already crossed by the vertical line.
Those lines divide the plane into four quadrants. The quadrant containing points with arbitrarily large positive coordinates is the top-right quadrant.

The players score according to the number of brownie points in the quadrants. If a brownie point is crossed by a line, it doesn't count. Stan gets a point for each (uncrossed) brownie point in the top-right and bottom-left quadrants. Ollie gets a point for each (uncrossed) brownie point in the top-left and bottom-right quadrants.

Stan and Ollie each try to maximize his own score. When Stan plays, he considers the responses, and chooses a line which maximizes his smallest-possible score.

Input

Input contains a number of test cases. The data of each test case appear on a sequence of input lines. The first line of each test case contains a positive odd integer 1 < n < 200000 which is the number of brownie points. Each of the following n lines contains two integers, the horizontal (x) and vertical (y) coordinates of a brownie point. No two brownie points occupy the same place. The input ends with a line containing 0 (instead of the n of a test).

Output

For each input test, print a line of output in the format shown below. The first number is the largest score which Stan can assure for himself. The remaining numbers are the possible (high) scores of Ollie, in increasing order.

Sample Input

  1. 11
  2. 3 2
  3. 3 3
  4. 3 4
  5. 3 6
  6. 2 -2
  7. 1 -3
  8. 0 0
  9. -3 -3
  10. -3 -2
  11. -3 -4
  12. 3 -7
  13. 0

Sample Output

  1. Stan: 7; Ollie: 2 3;
  2.  
  3. 简述一下题意,给你一些点的xy坐标,过一点做垂线,再做一条水平线,且该水平线必须经过已经被第一条垂线穿过的点,将所有点分成了4份,Stan是左下右上点个数之和,Ollie是左上右下,
    求出Stan的值,使其最小值最大,并且输出该条垂线下,Stan取该值时,Ollie值的最大值,升序打印。
    思路:读题意,求个数之和,想到二维树状数组,看数据范围,变成偏序问题,离散化后一维树状数组即可,本题的细节主要是在如何求这四份,树状数组可以求出左下区域,那么就分别维护每个点上下左右各有多少点,结合左下就可以求出其他区域,如图:
  1.  

TL = 该点左侧的点-BL, TR = 该点上侧的点-TL, BR = 该点右侧的点-TR

  1.  

细节代码中有注释(补到线段树和扫描线再做一次

  1.  
  1. using namespace std;
  2. #define lowbit(x) ((x)&(-x))
  3. typedef long long LL;
  4.  
  5. const int maxm = 2e5+;
  6. const int INF = 0x3f3f3f3f;
  7.  
  8. int x[maxm], y[maxm], numx[maxm], numy[maxm], Left[maxm], Right[maxm], \
  9. Upper[maxm], Lower[maxm], n, totx, toty, C[maxm], ally[maxm], allx[maxm], \
  10. sumLeft[maxm], sumRight[maxm], sumUpper[maxm], sumLower[maxm], sumx[maxm], sumy[maxm], \
  11. ans1[maxm], ans2[maxm];
  12. bool vis[maxm];
  13.  
  14. void init() {
  15. totx = toty = ;
  16. memset(ans1, , sizeof(ans1)), memset(ans2, -, sizeof(ans2));
  17. memset(C, , sizeof(C)), memset(numx, , sizeof(numx)), memset(numy, , sizeof(numy));
  18. memset(sumx, , sizeof(sumx)), memset(sumy, , sizeof(sumy)), memset(vis, , sizeof(vis));
  19. }
  20.  
  21. void add(int pos, int val) {
  22. for(; pos <= toty; pos += lowbit(pos))
  23. C[pos] += val;
  24. }
  25.  
  26. int getsum(int pos) {
  27. int ret = ;
  28. for(; pos; pos -= lowbit(pos))
  29. ret += C[pos];
  30. return ret;
  31. }
  32.  
  33. struct Node {
  34. int x, y;
  35. Node(){}
  36. bool operator<(const Node &a) const {
  37. return x < a.x || (x == a.x && y < a.y);
  38. }
  39. } Nodes[maxm];
  40.  
  41. int main() {
  42. while(scanf("%d", &n) && n) {
  43. init();
  44. // 读入并对x,y离散化
  45. for(int i = ; i <= n; ++i) {
  46. scanf("%d%d", &x[i], &y[i]);
  47. allx[++totx] = x[i], ally[++toty] = y[i];
  48. }
  49. sort(allx+, allx++totx), sort(ally+,ally++toty);
  50. int lenx = unique(allx+, allx++totx)-allx-, leny = unique(ally+,ally++toty)-ally-;
  51. int nodenum = ;
  52. for(int i = ; i <= n; ++i) {
  53. Nodes[++nodenum].x = lower_bound(allx+,allx+lenx+, x[i]) - allx;
  54. Nodes[nodenum].y = lower_bound(ally+,ally+leny+, y[i]) - ally;
  55. }
  56. sort(Nodes+, Nodes+nodenum+);
  57. // 求出每个点上下左右垂直有多少个点
  58. for(int i = ; i <= nodenum; ++i) {
  59. Lower[i] = numx[Nodes[i].x]++;
  60. Left[i] = numy[Nodes[i].y]++;
  61. }
  62. for(int i = ; i <= nodenum; ++i) {
  63. Upper[i] = numx[Nodes[i].x] - Lower[i] - ;
  64. Right[i] = numy[Nodes[i].y] - Left[i] - ;
  65. }
  66. // 求出坐标xi=1,2,的左侧 yi=1,2,的下侧 一共有多少个点 水平/垂直线(包括该线)
  67. for(int i = ; i <= lenx; ++i) {
  68. sumx[i] = sumx[i-] + numx[i];
  69. }
  70. for(int i = ; i <= leny; ++i) {
  71. sumy[i] = sumy[i-] + numy[i];
  72. }
  73. // 计算每个点上下左右侧一共有几个点
  74. for(int i = ; i <= nodenum; ++i) {
  75. int x = Nodes[i].x, y = Nodes[i].y;
  76. sumLeft[i] = sumx[x-];
  77. sumRight[i] = sumx[lenx] - sumx[x];
  78. sumLower[i] = sumy[y-];
  79. sumUpper[i] = sumy[leny] - sumy[y];
  80. }
  81. for(int i = ; i <= nodenum; ++i) {
  82. int x = Nodes[i].x, y = Nodes[i].y;
  83. int BL = getsum(y-) - Lower[i];
  84. int TL = sumLeft[i] - BL - Left[i];
  85. int TR = sumUpper[i] - TL - Upper[i];
  86. int BR = sumLower[i] - BL - Lower[i];
  87. add(y, );
  88. if(BL + TR < ans1[x]) {
  89. ans1[x] = BL + TR, ans2[x] = TL + BR;
  90. } else if(BL + TR == ans1[x]) ans2[x] = max(ans2[x], TL + BR);
  91. }
  92. int ans = ;
  93. for(int i = ; i <= lenx; ++i)
  94. if(ans1[i] < INF)
  95. ans = max(ans, ans1[i]);
  96. printf("Stan: %d; Ollie:",ans);
  97. for(int i = ; i <= lenx; ++i)
  98. if(ans1[i] == ans) vis[ans2[i]] = true;
  99. for(int i = ; i <= n; ++i)
  100. if(vis[i])
  101. printf(" %d", i);
  102. printf(";\n");
  103. }
  104. }
  1.  
  1.  
  1.  

Day6 - E - Brownie Points II POJ - 2464的更多相关文章

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

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

  2. UVA10869 - Brownie Points II(线段树)

    UVA10869 - Brownie Points II(线段树) 题目链接 题目大意:平面上有n个点,Stan和Ollie在玩游戏,游戏规则是:Stan先画一条竖直的线作为y轴,条件是必需要经过这个 ...

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

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

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

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

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

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

  6. POJ 2464 Brownie Points II(树状数组)

    一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要O(n^2),结果发现自己想多了... 其实是每个点画根竖线和横线就好,对于相同竖线统计(一直不包含线上点)右上左下总 ...

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

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

  8. HDOJ-1156 Brownie Points II 线段树/树状数组(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1156 在一张二位坐标系中,给定n个点的坐标,玩一个划线游戏(线必须穿过点),Stan先手画一条垂直的线,然后Ol ...

  9. [转载]完全版线段树 by notonlysuccess大牛

    原文出处:http://www.notonlysuccess.com/ (好像现在这个博客已经挂掉了,在网上找到的全部都是转载) 今天在清北学堂听课,听到了一些很令人吃惊的消息.至于这消息具体是啥,等 ...

随机推荐

  1. ECS 系统 Entity-Component-System

    已经推出了很久了, 貌似也有一些人开始使用, 我是在看守望先锋的程序设计相关文章的时候看到 ECS 的, 从它的设计逻辑上看, 核心就是 Composition over inheritance (o ...

  2. 多数据库:SQLHelper

    //=============================================================================== // This file is ba ...

  3. PAT T1012 Greedy Snake

    直接暴力枚举,注意每次深搜完状态的还原~ #include<bits/stdc++.h> using namespace std; ; int visit[maxn][maxn]; int ...

  4. mapreduce程序执行过程

    1.客户端程序,设置作业相关的配置和计算输入分片信息,向RM获取一个JOBID,提交作业信息(分片)到以作业ID为目录下,通知APP——MASTER 2.APP——MASTER,读取指定目录下的作业信 ...

  5. 吴裕雄--天生自然 JAVA开发学习:java使用Eclipel连接数据库

    1:jar可到Mysql官网下载:地址Mysql 连接jar包.:https://dev.mysql.com/downloads/connector/j/如图,在下拉列表框中选择Platform In ...

  6. Windows驱动开发-IRP超时处理

    IRP被送到底层驱动程序以后,由于硬件设备的问题,IRP不能得到及时处理,甚至有可能永远不会被处理,这时候需要对IRP超时情况进行处理,一旦在规定时间内,IRP没有被处理,操作系统就会进入到IRP的处 ...

  7. 「Luogu P1383 高级打字机」

    一道非常基础的可持久化数据结构题. 前置芝士 可持久化线段树:实现的方法主要是主席树. 具体做法 这个基本就是一个模板题了,记录一下每一个版本的字符串的长度,在修改的时候就只要在上一个版本后面加上一个 ...

  8. Uart学习笔记

    分享一个蛮好的链接:https://blog.csdn.net/wordwarwordwar/article/details/73662379 今天在看的资料是S家的DW_apb_uart的官方文档. ...

  9. ssm 框架 使用ajax异步,实现登陆

    只是简单写一下 js.jsp.和controller jsp <%@ page contentType="text/html;charset=UTF-8" language= ...

  10. 「POJ3613」Cow Relays

    「POJ3613」Cow Relays 传送门 就一个思想:\(N\) 遍 \(\text{Floyd}\) 求出经过 \(N\) 个点的最短路 看一眼数据范围,想到离散化+矩阵快速幂 代码: #in ...