2464 -- Brownie Points II

Problem - 1156

  hdu分类线段树的题。题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通过在垂线上的点画一条平行线。他们的得分是stan在一三象限中有多少点,ollie在二四象限中共有多少点。在平行线和垂线的点不算任何人的。

  开始的时候以为暴力二维线段树,结果发现点的数目也太庞大了。后来想了一想,只是统计这么几个区域,逐个插点就可以的嘛。用一个树状数组存下y坐标中相应位置的点的个数,向前向后做两次差点即可!

  错了一次忘记将答案unique,然后就AC了。

代码及debug的数据如下:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map> using namespace std; const int N = ;
inline int lowbit(int x) { return (-x) & x;}
struct BIT {
int c[N];
void init() { memset(c, , sizeof(c));}
void insert(int x) { x += ; for (int i = x; i < N; i += lowbit(i)) c[i]++;}
int query(int x) { int ret = ; for ( ; x > ; x -= lowbit(x)) ret += c[x]; return ret;}
int query(int l, int r) { if (l > r) return ; l += , r += ; return query(r) - query(l - );}
} bit; typedef pair<int, int> PII;
PII sc[N], pt[N], buf[N];
int y[N];
map<int, int> yid;
const int INF = 0x7fffffff; int main() {
// freopen("in", "r", stdin);
int n;
while (~scanf("%d", &n) && n) {
memset(sc, , sizeof(sc));
for (int i = ; i < n; i++) {
scanf("%d%d", &pt[i].first, &pt[i].second);
y[i] = pt[i].second;
}
sort(y, y + n);
sort(pt, pt + n);
int m = unique(y, y + n) - y;
for (int i = ; i < m; i++) yid[y[i]] = i;
bit.init();
for (int i = , top = -; i < n; i++) {
if (i && pt[i - ].first != pt[i].first) {
while (~top) bit.insert(yid[buf[top--].second]);
// cout << "pop! " << i << endl;
}
buf[++top] = pt[i];
sc[i].first += bit.query(, yid[pt[i].second] - );
sc[i].second += bit.query(yid[pt[i].second] + , m - );
}
// for (int i = 0; i < n; i++) cout << sc[i].first << ' '; cout << endl;
// for (int i = 0; i < n; i++) cout << sc[i].second << ' '; cout << endl;
bit.init();
for (int i = n - , top = -; i >= ; i--) {
if (i != n - && pt[i + ].first != pt[i].first) {
while (~top) bit.insert(yid[buf[top--].second]);
// cout << "pop~ " << i << endl;
}
buf[++top] = pt[i];
sc[i].first += bit.query(yid[pt[i].second] + , m - );
sc[i].second += bit.query(, yid[pt[i].second] - );
}
// for (int i = 0; i < n; i++) cout << sc[i].first << ' '; cout << endl;
// for (int i = 0; i < n; i++) cout << sc[i].second << ' '; cout << endl;
vector<int> tmp, best;
int fi = , se, mx = -INF;
sc[n] = PII(-, -);
while (fi < n) {
se = fi;
while (pt[fi].first == pt[se].first) se++;
int tmx = INF;
// cout << fi << ' ' << se << endl;
for (int i = fi; i < se; i++) {
if (tmx > sc[i].first) {
tmx = sc[i].first;
tmp.clear();
tmp.push_back(sc[i].second);
} else if (tmx == sc[i].first) tmp.push_back(sc[i].second);
}
fi = se;
if (mx < tmx) {
mx = tmx;
best = tmp;
} else if (mx == tmx) {
for (int i = , sz = tmp.size(); i < sz; i++) {
best.push_back(tmp[i]);
}
}
}
// cout << mx << ' ' << best.size() << endl;
sort(best.begin(), best.end());
printf("Stan: %d; Ollie:", mx);
int t = (int) (unique(best.begin(), best.end()) - best.begin());
while (best.size() > t) best.pop_back();
for (int i = , sz = best.size(); i < sz; i++) cout << ' ' << best[i]; cout << ';' << endl;
}
return ;
}

——written by Lyon

hdu 1156 && poj 2464 Brownie Points II (BIT)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. Day6 - E - Brownie Points II POJ - 2464

    Stan and Ollie play the game of Odd Brownie Points. Some brownie points are located in the plane, at ...

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

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

  9. Hdu 1156

    题目链接 Brownie Points II Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

随机推荐

  1. 轮播图js版&jQ版

    JS版轮播图 html部分和css部分自己任意定 主要构成: 1,一个固定的框 超出框的部分隐藏 2,几张图片float:left 3,下部下原点,点击切换,切换到不同的张都有红色显示 4,左右两个大 ...

  2. oracle-DML-2

    1.update 语句 update  table set  [column,column......] where  column ='' 示例: update   customers set   ...

  3. arcgis点密度专题

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. go语言第一问:在其他地方执行编译go语言程序,结果会在哪个地方产生?

    1.我们看执行编译go语言程序中命令,没有找到exe文件.

  5. Django创建对象的create和save方法

    Django的模型(Model)的本质是类,并不是一个具体的对象(Object).当你设计好模型后,你就可以对Model进行实例化从而创建一个一个具体的对象.Django对于创建对象提供了2种不同的s ...

  6. 移动端的vh 和 vw简介和使用场景

    vw 相对于视窗的宽度:视窗宽度是100vw:vh则类似,是相对于视窗的高度,视窗高度是100vh. 这里的视窗指的又是啥? 是浏览器内部宽度大小(window.innerWidth)? 是整个浏览器 ...

  7. 24种编程语言的Hello World程序

    24种编程语言的Hello World程序 这篇文章主要介绍了 24 种编程语言的 Hello World 程序,包括熟知的 Java.C 语言.C++.C#.Ruby.Python.PHP 等编程语 ...

  8. LocalDateTime计算时间差

    LocalDateTime 为java8的新特性之一 LocalDateTime.now() 获得当前时间 java.time.Duration duration = java.time.Durati ...

  9. Linux使用及命令

    #命令模式下输入:光标移动到第34行第15个字符 <Enter>15l(这是小写的L) ctrl+u删除光标前面的字符 ctrl+j删除光标后面的字符 在Linux下用VIM打开大小几个G ...

  10. mariadb配置文件优化参数

    mariadb数据库优化需要根据自己业务需求以及根据硬件配置来进行参数优化,下面是一些关于mariadb数据库参数优化的配置文件. 1 如下为128G内存32线程处理器的mariadb配置参数优化: ...