链接:
http://codeforces.com/contest/652/problem/D
题意:
给你n条线段,输出每条线段包含多少条线段,线段端点不重复
题解:
先把线段的所有端点放到一个vector里面,同时还要记下是哪条线段的起点或终点,所以用pair
id为正表示起点,id为负表示终点,然后遍历vector遇到为正的就加入到树状数组中,负的就减去,同时更新答案
怎么更新树状数组呢,需要用cnt和map来记下这条线段是第几个被加入进来的,详细的看代码
题解:
31 int n; 32 int ans[MAXN]; 33 int bit[MAXN]; 34 35 void add(int i, int x) { 36 while (i <= n) bit[i] += x, i += i&-i; 37 } 38 39 int sum(int i) { 40 int s = 0; 41 while (i) s += bit[i], i -= i&-i; 42 return s; 43 } 44 45 int main() { 46 ios::sync_with_stdio(false), cin.tie(0); 47 cin >> n; 48 vector<PII> v; 49 rep(i, 1, n + 1) { 50 int l, r; 51 cin >> l >> r; 52 v.pb(mp(l, i)); 53 v.pb(mp(r, -i)); 54 } 55 sort(all(v)); 56 int cnt = 1; 57 map<int, int> mmp; 58 rep(i, 0, v.size()) { 59 int x = v[i].first; 60 int id = v[i].second; 61 if (id > 0) { 62 mmp[id] = cnt; 63 add(cnt++, 1); 64 } 65 else { 66 id = -id; 67 int pos = mmp[id]; 68 add(pos, -1); 69 ans[id] = cnt - 1 - pos - sum(cnt - 1) + sum(pos); 70 } 71 } 72 rep(i, 1, n + 1) cout << ans[i] << endl; 73 return 0; 74 }