hdu 1156 && poj 2464 Brownie Points II (BIT)
hdu分类线段树的题。题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通过在垂线上的点画一条平行线。他们的得分是stan在一三象限中有多少点,ollie在二四象限中共有多少点。在平行线和垂线的点不算任何人的。
开始的时候以为暴力二维线段树,结果发现点的数目也太庞大了。后来想了一想,只是统计这么几个区域,逐个插点就可以的嘛。用一个树状数组存下y坐标中相应位置的点的个数,向前向后做两次差点即可!
错了一次忘记将答案unique,然后就AC了。
代码及debug的数据如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #include <map> 7 8 using namespace std; 9 10 const int N = 222222; 11 inline int lowbit(int x) { return (-x) & x;} 12 struct BIT { 13 int c[N]; 14 void init() { memset(c, 0, sizeof(c));} 15 void insert(int x) { x += 10; for (int i = x; i < N; i += lowbit(i)) c[i]++;} 16 int query(int x) { int ret = 0; for ( ; x > 0; x -= lowbit(x)) ret += c[x]; return ret;} 17 int query(int l, int r) { if (l > r) return 0; l += 10, r += 10; return query(r) - query(l - 1);} 18 } bit; 19 20 typedef pair<int, int> PII; 21 PII sc[N], pt[N], buf[N]; 22 int y[N]; 23 map<int, int> yid; 24 const int INF = 0x7fffffff; 25 26 int main() { 27 // freopen("in", "r", stdin); 28 int n; 29 while (~scanf("%d", &n) && n) { 30 memset(sc, 0, sizeof(sc)); 31 for (int i = 0; i < n; i++) { 32 scanf("%d%d", &pt[i].first, &pt[i].second); 33 y[i] = pt[i].second; 34 } 35 sort(y, y + n); 36 sort(pt, pt + n); 37 int m = unique(y, y + n) - y; 38 for (int i = 0; i < m; i++) yid[y[i]] = i; 39 bit.init(); 40 for (int i = 0, top = -1; i < n; i++) { 41 if (i && pt[i - 1].first != pt[i].first) { 42 while (~top) bit.insert(yid[buf[top--].second]); 43 // cout << "pop! " << i << endl; 44 } 45 buf[++top] = pt[i]; 46 sc[i].first += bit.query(0, yid[pt[i].second] - 1); 47 sc[i].second += bit.query(yid[pt[i].second] + 1, m - 1); 48 } 49 // for (int i = 0; i < n; i++) cout << sc[i].first << ' '; cout << endl; 50 // for (int i = 0; i < n; i++) cout << sc[i].second << ' '; cout << endl; 51 bit.init(); 52 for (int i = n - 1, top = -1; i >= 0; i--) { 53 if (i != n - 1 && pt[i + 1].first != pt[i].first) { 54 while (~top) bit.insert(yid[buf[top--].second]); 55 // cout << "pop~ " << i << endl; 56 } 57 buf[++top] = pt[i]; 58 sc[i].first += bit.query(yid[pt[i].second] + 1, m - 1); 59 sc[i].second += bit.query(0, yid[pt[i].second] - 1); 60 } 61 // for (int i = 0; i < n; i++) cout << sc[i].first << ' '; cout << endl; 62 // for (int i = 0; i < n; i++) cout << sc[i].second << ' '; cout << endl; 63 vector<int> tmp, best; 64 int fi = 0, se, mx = -INF; 65 sc[n] = PII(-1, -1); 66 while (fi < n) { 67 se = fi; 68 while (pt[fi].first == pt[se].first) se++; 69 int tmx = INF; 70 // cout << fi << ' ' << se << endl; 71 for (int i = fi; i < se; i++) { 72 if (tmx > sc[i].first) { 73 tmx = sc[i].first; 74 tmp.clear(); 75 tmp.push_back(sc[i].second); 76 } else if (tmx == sc[i].first) tmp.push_back(sc[i].second); 77 } 78 fi = se; 79 if (mx < tmx) { 80 mx = tmx; 81 best = tmp; 82 } else if (mx == tmx) { 83 for (int i = 0, sz = tmp.size(); i < sz; i++) { 84 best.push_back(tmp[i]); 85 } 86 } 87 } 88 // cout << mx << ' ' << best.size() << endl; 89 sort(best.begin(), best.end()); 90 printf("Stan: %d; Ollie:", mx); 91 int t = (int) (unique(best.begin(), best.end()) - best.begin()); 92 while (best.size() > t) best.pop_back(); 93 for (int i = 0, sz = best.size(); i < sz; i++) cout << ' ' << best[i]; cout << ';' << endl; 94 } 95 return 0; 96 }
——written by Lyon