poj 2528 Mayor's posters(线段树)

题目:http://poj.org/problem?id=2528

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度。现在往墙上贴N张海报,每张海报的宽度是任意的,

但是必定是单位宽度的整数倍,且<=1QW。后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖

先贴的海报。现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?

 

(离散化)+ 线段树

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 const int maxn = 10000+10;
  7 int n, cnt;
  8 int map[2*maxn][2], ans, f[2*maxn];
  9 struct node
 10 {
 11     int l, r, n;  //n代表是哪种颜色
 12 } a[8*maxn];
 13 struct node2
 14 {
 15     int point, num;  //原来点的编号, 新编的号
 16 } s[8*maxn];
 17 void init(int l, int r, int i) //建树
 18 {
 19     a[i].l = l;
 20     a[i].r = r;
 21     a[i].n = 0;
 22     if(l != r)
 23     {
 24         int mid = (l+r)/2;
 25         init(l, mid, 2*i);
 26         init(mid+1, r, 2*i+1);
 27     }
 28 }
 29 void insert(int i, int l, int r, int m)//从第i个点,查找区间【l,r】,并把颜色标记为m
 30 {
 31     if(a[i].l == l && a[i].r == r)
 32     {
 33         a[i].n = m;
 34         return;
 35     }
 36     int mid = (a[i].l+a[i].r)/2;
 37     if(a[i].n>0)  //颜色已有,对其子树赋值
 38     {
 39         a[2*i].n = a[i].n;
 40         a[2*i+1].n = a[i].n;
 41         a[i].n = 0;
 42     }
 43     if(l >= a[2*i+1].l)
 44     insert(2*i+1, l, r, m);
 45     else if(r <= a[2*i].r)
 46     insert(2*i, l, r, m);
 47     else
 48     {
 49         insert(2*i, l, mid, m);
 50         insert(2*i+1, mid+1, r, m);
 51     }
 52 }
 53 void solve(int i)
 54 {
 55     if(a[i].n)
 56     {
 57         if(!f[a[i].n])
 58         {
 59             ans++;
 60             f[a[i].n] = 1;
 61         }
 62         return;
 63     }
 64     solve(2*i);
 65     solve(2*i+1);
 66 }
 67 int cmp(node2 x, node2 y)
 68 {
 69     return x.point<y.point;
 70 }
 71 
 72 int main()
 73 {
 74     int t, i, tmp, cnt;
 75     scanf("%d", &t);
 76     while(t--)
 77     {
 78         scanf("%d", &n);
 79         for(i = 0; i < n; i++)
 80         {
 81             scanf("%d%d", &map[i][0], &map[i][1]);
 82             s[i*2].point = map[i][0];
 83             s[i*2+1].point = map[i][1];
 84             s[2*i].num = -(i+1);
 85             s[2*i+1].num = i+1;
 86         }
 87         sort(s, s+2*n, cmp);
 88         tmp = s[0].point;
 89         cnt = 1;
 90         for(i = 0; i < 2*n; i++)
 91         {
 92             if(tmp != s[i].point)
 93             {
 94                 cnt++;
 95                 tmp = s[i].point;
 96             }
 97             if(s[i].num < 0)
 98                 map[-s[i].num-1][0] = cnt;
 99             else
100                 map[s[i].num-1][1] = cnt;
101         }
102         init(1, cnt, 1);
103         for(i = 0; i < n; i++)
104             insert(1, map[i][0], map[i][1], i+1);
105         memset(f, 0, sizeof(f));
106         ans = 0;
107         solve(1);
108         printf("%d\n",ans);
109     }
110     return 0;
111 }

 

posted @ 2014-02-18 19:59  水门  阅读(181)  评论(0编辑  收藏  举报