【树状数组】HDU 5372 Segment Game
题意:加线段,删线段,每次加线段询问当前线段完整覆盖了多少条线段
思路:对于新插入的线段,查询有多少个线段左端点大于等于该线段的左端点。 再查询有多少个线段的右端点大于该线段右端点, 两者之差就是答案。用两个树状数组搞定。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; template <class T> inline bool rd(T &ret) { char c; int sgn; if(c = getchar() , c == EOF) return false; while(c != '-' && (c < '0' || c > '9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return true; } typedef long long ll; const int MAX_N = 900007; int n; ll bit[MAX_N][2]; int sum(int i, int id) { int s = 0; while (i > 0) { s += bit[i][id]; i -= i & -i; } return s; } int up; void add(int i, int x, int id) { while (i <= up) { bit[i][id] += x; i += i & -i; } } struct Query { int t, l, r; Query() { } Query(int _t, int _l, int _r) { t = _t; l = _l; r = _r; } }; int id[MAX_N]; bool vis[MAX_N]; Query Q[MAX_N]; vector<ll> a; int main() { int cas = 0; while (1 == scanf("%d", &n)) { memset(bit, 0, sizeof bit); memset(vis, false, sizeof vis); a.clear(); int dec = 0, cnt = 0, Z = 1; for (int i = 1; i <= n; ++i) { rd(Q[i].t), rd(Q[i].l); if (Q[i].t == 0) { id[Z++] = i; Q[i].r = Q[i].l + i - dec; a.push_back(Q[i].l), a.push_back(Q[i].r); } else ++dec; } sort(a.begin(),a.end()); vector<ll>::iterator iter = unique(a.begin(), a.end()); a.erase(iter,a.end()); printf("Case #%d:\n", ++cas); up = a.size(); for (int i = 1; i <= n; ++i) { if (Q[i].t == 0) { int l = (lower_bound(a.begin(), a.end(), Q[i].l) - a.begin()) + 1; int r = (lower_bound(a.begin(), a.end(), Q[i].r) - a.begin()) + 1; int ans = sum(up, 0) - sum(l - 1, 0) - sum(up, 1) + sum(r, 1); printf("%d\n", ans); vis[i] = true; add(l, 1, 0); add(r, 1, 1); } else { int vl = id[Q[i].l]; int l = (lower_bound(a.begin(), a.end(), Q[vl].l) - a.begin()) + 1; int r = (lower_bound(a.begin(), a.end(), Q[vl].r) - a.begin()) + 1; if (vis[vl]) { add(l, -1, 0); add(r, -1, 1); } } } } return 0; }