hdu 1156 && poj 2464 Brownie Points II (BIT)
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)的更多相关文章
- POJ - 2464 Brownie Points II 【树状数组 + 离散化】【好题】
题目链接 http://poj.org/problem?id=2464 题意 在一个二维坐标系上 给出一些点 Stan 先画一条过一点的水平线 Odd 再画一条 过Stan那条水平线上的任一点的垂直线 ...
- POJ 2464 Brownie Points II (树状数组,难题)
题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...
- POJ 2464 Brownie Points II(树状数组)
一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要O(n^2),结果发现自己想多了... 其实是每个点画根竖线和横线就好,对于相同竖线统计(一直不包含线上点)右上左下总 ...
- POJ 2464 Brownie Points II --树状数组
题意: 有点迷.有一些点,Stan先选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画一条横线.Stan选这两条直线分成的左下和右上部分的点,Ollie选左上和右下部分的点.Sta ...
- UVA10869 - Brownie Points II(线段树)
UVA10869 - Brownie Points II(线段树) 题目链接 题目大意:平面上有n个点,Stan和Ollie在玩游戏,游戏规则是:Stan先画一条竖直的线作为y轴,条件是必需要经过这个 ...
- UVA 10869 - Brownie Points II(树阵)
UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分 ...
- 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 ...
- HDOJ-1156 Brownie Points II 线段树/树状数组(模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1156 在一张二位坐标系中,给定n个点的坐标,玩一个划线游戏(线必须穿过点),Stan先手画一条垂直的线,然后Ol ...
- Hdu 1156
题目链接 Brownie Points II Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
随机推荐
- RQNOJ PID192 梦幻大PK [2017年6月计划 二分图02]
PID192 / 梦幻大PK ☆ 提交你的代码 查看讨论和题解 你还木有做过哦 我的状态 查看最后一次评测记录 质量 7 题目评价 质量 7 ★★★★★ ★★★★☆ ★★★☆☆ ★★☆ ...
- 考试总结 模拟28(W)
心得: 状态极差,都怪放假,上一套的T3没改完,今天考试没有一点状态,开学恐惧症.(不恐惧作业或一调但还是很茫然) T1能A掉实在是意外,杂题T1没做过,可能是人品守恒,(丢了钱今天才发现以后一定锁柜 ...
- 数组的方法之(Array.prototype.filter() 方法)
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素. 注意: filter() 不会对空数组进行检测. 注意: filter() 不会改变原始 ...
- MR25H10-1Mb密度SPI串行接口MRAM
everspin的MR25H10是一个1,048,576位磁阻随机存取存储器(MRAM)设备,由131,072个8位字组成.MR25H10提供串行EEPROM和串行闪存兼容的读/写时序,没有写延迟,并 ...
- win10下安装mongodb(解压版)
首先到官网下载安装包.(https://www.mongodb.com/download-center#community) 1.创建mongodb目录 2.配置文件mongodb.config 3. ...
- cmake时选择的VS生成器
运行cmake --help 在得到的输出中可以得到下面的结果:
- openssl生成SSL证书的流程 - moonhillcity的博客 - CSDN博客
1.安装openssl 之后在/usr/lib/ssl目录下(ubuntu系统,用whereis查下ssl目录即可)下找到openssl.cnf,拷贝到工作目录下. 2.工作目录下新建demoCA文件 ...
- 本地 vs. 云:大数据厮杀的最终幸存者会是谁?— InfoQ专访阿里云智能通用计算平台负责人关涛
摘要: 本地大数据服务是否进入消失倒计时?云平台大数据服务最终到底会趋向多云.混合云还是单一公有云?集群规模增大,上云成本将难以承受是误区还是事实?InfoQ 将就上述问题对阿里云智能通用计算平台负责 ...
- Java练习 SDUT-2192_救基友记2
救基友记2 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 屌丝WP的好基友CZ又被妖鬼给抓走了(CZ啊,CZ-.怎么说 ...
- jQuery之父:坚持每天都要写代码
关于作者:John Resig, jQuery之父,同时也是Pro Javascript Techniques和Secrets of the JavaScript Ninja的作者.他目前主持 Kha ...