sdut 2427 Mayor\'s posters(线段树+离散化)

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2427

 

View Code
  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <cstdio>
  5 #define MAX 20001
  6 using namespace std;
  7 
  8 struct node
  9 {
 10     int li;
 11     int num;
 12 }st[MAX*4];//用于离散化的数组
 13 int tree[MAX*4];
 14 int ht[MAX][2];//用于存储端点的数组
 15 int vis[MAX],sum;
 16 bool cmp(node a,node b)
 17 {
 18     return a.li<b.li;
 19 }
 20 void build(int l,int r,int w)
 21 {
 22     if(l==r)
 23     {
 24         tree[w]=0;//端点值为0
 25         return ;
 26     }
 27     int m=(l+r)/2;
 28     build(l,m,w*2);
 29     build(m+1,r,w*2+1);
 30 }
 31 void update(int L,int R,int l,int r,int w, int x)
 32 {
 33     if(L==l&&R==r)
 34     {
 35         tree[w]=x;//标记
 36         return ;
 37     }
 38     if(tree[w]>0&&tree[w]!=x)
 39     {
 40         tree[w*2+1]=tree[w*2]=tree[w];//向下传递
 41         tree[w]=0;//删除标记
 42     }
 43     int m=(l+r)/2;
 44     if(L>m)
 45     update(L,R,m+1,r,w*2+1,x);
 46     else if(R<=m)
 47         update(L,R,l,m,w*2,x);
 48         else
 49         {
 50             update(L,m,l,m,w*2,x);
 51             update(m+1,R,m+1,r,w*2+1,x);
 52         }
 53 }
 54 void query(int w)
 55 {
 56     if(tree[w]!=0)
 57     {
 58         if(!vis[tree[w]])
 59         {
 60             vis[tree[w]]=1;//标记
 61             sum++;
 62         }
 63         return ;
 64     }
 65     query (w*2);
 66     query(w*2+1);
 67 }
 68 int main()
 69 {
 70     int t,n,i;
 71     scanf("%d",&t);
 72     while(t--)
 73     {
 74         scanf("%d",&n);
 75         for(i=0;i<n;i++)
 76         {
 77             scanf("%d%d",&ht[i][0],&ht[i][1]);
 78             st[2*i].li=ht[i][0];
 79             st[2*i].num=-(i+1);//负号 记录左面的端点
 80             st[2*i+1].li=ht[i][1];
 81             st[2*i+1].num=i+1;//记录右面端点
 82         }
 83         sort(st,st+n*2,cmp);
 84         int temp=st[0].li,tp=1;//按小到大离散,tp标记
 85         for(i=0;i<2*n;i++)
 86         {
 87             if(st[i].li!=temp)//判断是否重复
 88             {
 89                 tp++;
 90                 temp=st[i].li;
 91             }
 92             if(st[i].num<0)//是否为左端点
 93             {
 94                 ht[-st[i].num-1][0]=tp;
 95             }
 96             else
 97             {
 98                 ht[st[i].num-1][1]=tp;
 99             }
100         }
101         build(1,tp,1);
102         memset(vis,0,sizeof(vis));
103         for(i=0;i<n;i++)
104         {
105             update(ht[i][0],ht[i][1],1,tp,1,i+1);//防止i=0情况
106         }
107         sum=0;
108         query(1);
109         printf("%d\n",sum);
110     }
111     return 0;
112 }
posted @ 2012-08-27 22:14  琳&leen  阅读(130)  评论(0编辑  收藏  举报