Educational Codeforces Round 10 D. Nested Segments 树状数组

链接:

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 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 }

 

你可能感兴趣的:(Educational Codeforces Round 10 D. Nested Segments 树状数组)