POJ2528+线段树

见代码。

  1 /*
  2 线段树+Lazy
  3 题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度。
  4 现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW。
  5 后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报。
  6 现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?
  7 (PS:看见一部分也算看到。)
  8 */
  9 #include<stdio.h>
 10 #include<string.h>
 11 #include<stdlib.h>
 12 #include<algorithm>
 13 #include<iostream>
 14 #include<queue>
 15 #include<map>
 16 #include<stack>
 17 #include<set>
 18 #include<math.h>
 19 using namespace std;
 20 typedef long long int64;
 21 //typedef __int64 int64;
 22 typedef pair<int64,int64> PII;
 23 #define L(x) (x<<1)
 24 #define R(x) (x<<1|1)
 25 #define MP(a,b) make_pair((a),(b)) 
 26 const int maxn = 20005;
 27 const int inf = 0x7fffffff;
 28 const double pi=acos(-1.0);
 29 const double eps = 1e-8;
 30 
 31 struct Node{
 32     int L,R,color;
 33 }tree[ maxn<<2 ];
 34 struct NODE{
 35     int L,R;
 36     bool operator<(const NODE &tmp ) const{
 37         return R<tmp.R;
 38     }
 39 }a[ maxn ];
 40 int myhash[ maxn ];
 41 int ANS;
 42 int vis[ maxn ];
 43 
 44 int lisanhua( int k ){
 45     sort( myhash,myhash+k );
 46     int cnt = unique( myhash,myhash+k ) - myhash;
 47     return cnt;
 48 }
 49 
 50 void build( int L,int R,int n ){
 51     if( L==R ){
 52         tree[ n ].L = L;
 53         tree[ n ].R = R;
 54         tree[ n ].color = 0;
 55         return ;
 56     }
 57     tree[ n ].L = L;
 58     tree[ n ].R = R;
 59     tree[ n ].color = 0;
 60     int mid = (L+R)/2;
 61     build( L,mid,L(n) );
 62     build( mid+1,R,R(n) );
 63 }
 64 
 65 void PushDown( int n,int new_color ){
 66     if( tree[ n ].color!=0&&tree[ n ].color!=new_color ){
 67         tree[ L(n) ].color = tree[ R(n) ].color = tree[ n ].color;
 68         tree[ n ].color = 0;
 69     }
 70 }
 71 
 72 void update( int x,int y,int new_color,int L,int R,int n ){
 73     if( x==L&&y==R ){
 74         tree[ n ].color = new_color;
 75         return ;
 76     }
 77     PushDown( n,new_color );
 78     int mid = (L+R)/2;
 79     if( mid>=y ) update( x,y,new_color,L,mid,L(n) );
 80     else if( mid<x ) update( x,y,new_color,mid+1,R,R(n) );
 81     else {
 82         update( x,mid,new_color,L,mid,L(n) );
 83         update( mid+1,y,new_color,mid+1,R,R(n) );
 84     }
 85 }
 86 
 87 void query( int n ){
 88     if( tree[n].color ){
 89         if( vis[tree[n].color]==0 ){
 90             vis[tree[n].color] = 1;
 91             ANS++;
 92         }
 93         return ;
 94     }
 95     //int mid = (tree[n].L+tree[n].R)/2;
 96     query( L(n) );
 97     query( R(n) );
 98 }
 99         
100 int main(){
101     int T;
102     scanf("%d",&T);
103     while( T-- ){
104         int n;
105         scanf("%d",&n);
106         int k = 0;
107         for( int i=1;i<=n;i++ ){
108             scanf("%d%d",&a[i].L,&a[i].R);
109             myhash[ k++ ] = a[i].L;
110             myhash[ k++ ] = a[i].R;
111         }
112         int cnt = lisanhua( k );
113         build( 1,cnt,1 );
114         //printf("build\n");
115         for( int i=1;i<=n;i++ ){
116             int x = lower_bound( myhash,myhash+cnt,a[i].L )-myhash;
117             int y = lower_bound( myhash,myhash+cnt,a[i].R )-myhash;
118             x++,y++;
119             //printf("i = %d\n",i);
120             //printf("x = %d, y=%d\n",x,y);
121             update( x,y,i,1,cnt,1 );
122         }
123         ANS = 0;
124         memset( vis,0,sizeof( vis ) );
125         //printf("query\n");
126         query( 1 );
127         printf("%d\n",ANS);
128     }
129     return 0;
130 }
View Code

 

posted @ 2013-08-22 15:44  xxx0624  阅读(414)  评论(0编辑  收藏  举报