Poj2528 Mayor's posters (线段树)

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

 

题意:一段区间,前后用线段覆盖,问最后能在区间上看到的不同的线段数目.

 

区间染色问题,以不同的颜色向区间染色,问最后区间上的颜色总数.

 

区间操作,用线段树解决,注意lazy:

 

#include<stdio.h> #include<string.h> #include<stdlib.h> #define M 40008 #define L(x) (x<<1) #define R(x) ((x<<1)|1) #define MID(x,y) ((x+y)>>1) typedef struct{ int l,r; }Poster; typedef struct{ int l,r,c;//c }SegTree; SegTree tr[M*3]; Poster p[M>>1]; int x[M],xn,y[M]; int ans,flag,n; int Cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; } void Cal(int ix) { int mid=MID(tr[ix].l,tr[ix].r); if(tr[ix].l==tr[ix].r) return; tr[R(ix)]=tr[L(ix)]=tr[ix]; tr[L(ix)].r=mid;tr[R(ix)].l=mid+1; tr[ix].c=1; } void Updata(int ix,Poster p) { int mid; if(tr[ix].c==2) return; if(!tr[ix].c) Cal(ix); if(p.l<=x[tr[ix].l]&&p.r>=x[tr[ix].r]){ flag=0;tr[ix].c=2;return ; } mid=MID(tr[ix].l,tr[ix].r); if(p.r<=x[mid]) Updata(L(ix),p); else if(p.l>x[mid]) Updata(R(ix),p); else Updata(L(ix),p),Updata(R(ix),p); if(tr[L(ix)].c==2&&tr[R(ix)].c==2) tr[ix].c=2; } int main() { int t,i,j; scanf("%d",&t); while(t--){ scanf("%d",&n); for(i=xn=0;i<n;i++){ scanf("%d%d",&p[i].l,&p[i].r); y[xn++]=p[i].l;y[xn++]=p[i].r; } qsort(y,xn,sizeof(int),Cmp); for(i=1,j=0;i<xn;i++){ if(y[i]==y[j]) continue; y[++j]=y[i]; }xn=j+1;x[0]=y[0]; for(i=j=1;i<xn;i++){ if(y[i]-y[i-1]>1) x[j++]=MID(y[i],y[i-1]); x[j++]=y[i]; }xn=j; tr[1].l=0;tr[1].r=xn-1;tr[1].c=0; for(ans=n,i=n-1;i>=0;i--){ flag=1; Updata(1,p[i]); ans-=flag; } printf("%d/n",ans); } return 0; }  

 

你可能感兴趣的:(Poj2528 Mayor's posters (线段树))