CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

题目链接:http://codeforces.com/problemset/problem/652/D

大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段。

方法是对所有线段的端点值离散化,按照左端点从大到小排序,顺着这个顺序处理所有线段,那么满足在它内部的线段一定是之前已经扫到过的。用树状数组判断有多少是在右端点范围内。

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <stdio.h>
 7 #include <math.h>
 8 #include <queue>
 9 #include <stack>
10 #include <map>
11 #include <ctime>
12 #include <set>
13 using namespace std;
14 
15 const int N=4e5+10;
16 int a[N];
17 int b[N];
18 int lowbit(int x) {
19     return x&(-x);
20 }
21 int get(int x) {
22     int ret=0;
23     while (x) {
24         ret+=a[x];
25         x-=lowbit(x);
26     }
27     return ret;
28 }
29 void add(int x,int add) {
30     while (x<N) {
31         a[x]+=add;
32         x+=lowbit(x);
33     }
34 }
35 struct Seg{
36     int l,r;
37     int id;
38 
39     Seg() { }
40 
41     Seg(int l, int r, int id) : l(l), r(r), id(id) { }
42     bool operator < (const Seg & o) const {
43         return l>o.l;
44     }
45 }seg[N];
46 int ans[N];
47 int main () {
48     int n;
49     scanf("%d",&n);
50     int t=0;
51     for (int i=1;i<=n;i++) {
52         scanf("%d %d",&seg[i].l,&seg[i].r);
53         b[t++]=seg[i].l;
54         b[t++]=seg[i].r;
55         seg[i].id=i;
56     }
57     sort(b,b+t);
58     int k=unique(b,b+t)-b;
59     for (int i=1;i<=n;i++) {
60         seg[i].l=lower_bound(b,b+t,seg[i].l)-b+1;
61         seg[i].r=lower_bound(b,b + t,seg[i].r)-b+1;
62     }
63     sort(seg+1,seg+1+n);
64     for (int i=1;i<=n;i++) {
65         int id=seg[i].id;
66         ans[id]=get(seg[i].r);
67         add(seg[i].r,1);
68     }
69     for (int i=1;i<=n;i++) {
70         printf("%d\n",ans[i]);
71     }
72     return 0;
73 }

 

posted @ 2016-04-15 11:58  活在夢裡  阅读(225)  评论(0编辑  收藏  举报