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

 

你可能感兴趣的:(poj)