您的位置:首页 > 其它

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

2013-07-05 16:20 369 查看
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 = 222222;
inline int lowbit(int x) { return (-x) & x;}
struct BIT {
int c
;
void init() { memset(c, 0, sizeof(c));}
void insert(int x) { x += 10; for (int i = x; i < N; i += lowbit(i)) c[i]++;}
int query(int x) { int ret = 0; for ( ; x > 0; x -= lowbit(x)) ret += c[x]; return ret;}
int query(int l, int r) { if (l > r) return 0; l += 10, r += 10; return query(r) - query(l - 1);}
} bit;

typedef pair<int, int> PII;
PII sc
, pt
, buf
;
int y
;
map<int, int> yid;
const int INF = 0x7fffffff;

int main() {
//    freopen("in", "r", stdin);
int n;
while (~scanf("%d", &n) && n) {
memset(sc, 0, sizeof(sc));
for (int i = 0; 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 = 0; i < m; i++) yid[y[i]] = i;
bit.init();
for (int i = 0, top = -1; i < n; i++) {
if (i && pt[i - 1].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(0, yid[pt[i].second] - 1);
sc[i].second += bit.query(yid[pt[i].second] + 1, m - 1);
}
//        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 - 1, top = -1; i >= 0; i--) {
if (i != n - 1 && pt[i + 1].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] + 1, m - 1);
sc[i].second += bit.query(0, yid[pt[i].second] - 1);
}
//        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 = 0, se, mx = -INF;
sc
= PII(-1, -1);
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 = 0, 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 = 0, sz = best.size(); i < sz; i++) cout << ' ' << best[i]; cout << ';' << endl;
}
return 0;
}


View Code

——written by Lyon
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: