要贴一些海报,由于宽度一样,看成 一些 线段 ,区间分别为 [L,R],按顺序贴海报,会覆盖,要问最后可以看到几张海报。。
线段树区间更新是很明显的,但是由于 数据 很大,不能直接搞,需要进行离散化处理
所谓离散化,就是 通过 处理将数据 化小,但是 保持 数据之间的大小关系。。
如 10 11 12 13 ===> 1 2 3 4
这个题目需要注意一点,就是 不能直接离散化,否则会造成错误
如 [ 1 ,9 ] [ 1 , 3 ] [ 5 , 9 ] ==> [ 1 , 4 ] [1 , 2 ] [ 3 , 4 ] ,这样结果 是 第一条线段被完全覆盖,但是实际上它 并没有 被完全覆盖
那么 我们 可以 在 1 3 5 9 中 比较的时候 出入一些数 1 (2) 3 (4) 5(6)7,在 相差大于 1 的两个数中间插入 一个夹在中间的数,就不会错了。。
#include<iostream> #include<algorithm> using namespace std; #define MAXN 50005 #define lson u<<1 #define rson u<<1|1 int ll[MAXN],rr[MAXN]; int dat[MAXN],cnt[MAXN<<2]; struct Node{ int lef,rig,delta,color; }T[MAXN<<2]; void Build(int u,int l,int r){ T[u].lef=l; T[u].rig=r; T[u].delta=0; if(l==r){T[u].color=0;return;} int mid=(l+r)>>1; Build(lson,l,mid); Build(rson,mid+1,r); } void Update(int u,int l,int r,int v){ if(l<=T[u].lef&&T[u].rig<=r){ T[u].delta=v; T[u].color=v; } else { if(T[u].delta){ T[lson].delta=T[u].delta; T[rson].delta=T[u].delta; T[lson].color=T[u].delta; T[rson].color=T[u].delta; T[u].delta=0; } if(r<=T[lson].rig)Update(lson,l,r,v); else if(l>=T[rson].lef)Update(rson,l,r,v); else { Update(lson,l,T[lson].rig,v); Update(rson,T[rson].lef,r,v); } T[u].color=v; } } void Query(int u){ if(T[u].lef==T[u].rig){cnt[T[u].color]++;return;} if(T[u].delta){ T[lson].delta=T[u].delta; T[rson].delta=T[u].delta; T[lson].color=T[u].delta; T[rson].color=T[u].delta; T[u].delta=0; } Query(lson); Query(rson); } int bsearch(int low,int high,int v){ while(low<high){ int mid=(low+high)>>1; if(dat[mid]==v)return mid; if(dat[mid]>v)high=mid; else low=mid+1; } return -1; } int main(){ int t; int N; scanf("%d",&t); while(t--){ scanf("%d",&N); int id=0,i,len; for(i=0;i<N;i++){ scanf("%d%d",&ll[i],&rr[i]); dat[id++]=ll[i]; dat[id++]=rr[i]; } sort(dat,dat+id); for(len=1,i=1;i<id;i++){ if(dat[i]!=dat[i-1])dat[len++]=dat[i]; } for(i=len-1;i>0;i--){ if(dat[i]!=dat[i-1]+1)dat[len++]=dat[i-1]+1; } sort(dat,dat+len); dat[len]=1000000000; //for(i=0;i<len;i++){printf("%d ",dat[i]);}puts(""); Build(1,1,len); memset(cnt,0,sizeof(cnt)); for(i=0;i<N;i++){ int L=bsearch(0,len,ll[i])+1; int R=bsearch(0,len,rr[i])+1; //printf("L%d R%d\n",L,R); Update(1,L,R,i+1); } Query(1); int ans=0; for(i=1;i<=len;i++) if(cnt[i])ans++; printf("%d\n",ans); } }