题目链接:POJ--2528 Mayor's posters

题目大意:给你一个无限长的板子,然后依次往上面贴n张等高的海报,问你最后能看到多少张海报。

思路分析:线段树区间更新问题,但是要注意,给的长度的可能非常大,有1e9,不加处理直接维护一个线段树肯定会

MLE,TLE,但是我们注意到一共最多只有2e4个点,因此我们可以用离散化的思想先对区间进行预处理,所谓的离散化,

在我理解看来就是将一个很大的区间映射为一个很小的区间,而不改变原有的大小覆盖关系,但是注意简单的离散化可能

会出现错误,给出下面两个简单的例子应该能体现普通离散化的缺陷:
例子一:1-10 1-4 5-10
例子二:1-10 1-4 6-10
普通离散化后都变成了[1,4][1,2][3,4]
线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被完全覆盖掉了呢?
例子一是完全被覆盖掉了,而例子二没有被覆盖

解决的办法则是对于距离大于1的两相邻点,中间再插入一个点,本题还用到了Lazy标记的思想

直接更新区间进行标记而先不对子节点进行处理,如果需要往下更新再将标记下传一层。

 

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 100010
#define LL long long
int a[maxn*4],ll[maxn],rr[maxn],lz[maxn*4];
bool fa[maxn*4];
vector<int>q;
int ans;
void init(){
  memset(a,-1,sizeof(a));
  memset(ll,0,sizeof(ll));
  memset(rr,0,sizeof(rr));
  memset(fa,0,sizeof(fa));
  q.clear();ans=0;
}
int getid(int x){
   return lower_bound(q.begin(),q.end(),x)-q.begin()+1;
}
void lazy(int in){
   if(a[in]>0){
       a[in*2]=a[in];
       a[in*2+1]=a[in];
       a[in]=-1;
   }
}
void updata(int l,int r,int x,int y,int in,int va){
   if(l==x&&r==y){
      a[in]=va;
      return ;
   }
   lazy(in);
   int mid=(l+r)/2;
   if(y<=mid){
      updata(l,mid,x,y,in*2,va);
   }else if(x>mid){
      updata(mid+1,r,x,y,in*2+1,va);
   }else{
      updata(l,mid,x,mid,in*2,va);
      updata(mid+1,r,mid+1,y,in*2+1,va);
   }

}
void query(int l,int r,int in){
   //cout<<a[in]<<endl;
   if(a[in]>0){
       if(!fa[a[in]]){
          fa[a[in]]=1;
          ans++;
       }
       return ;
   }
   if(l==r) return ;
   int mid=(l+r)/2;
   query(l,mid,in*2);
   query(mid+1,r,in*2+1);

}
int main(){
   int t;
   cin>>t;
   while(t--){
      init();
      int n,mx=0;
      cin>>n;
      for(int j=1;j<=m;j++){
         cin>>ll[j]>>rr[j];
         q.push_back(ll[j]);
         q.push_back(rr[j]);
      }
      sort(q.begin(),q.end());

      q.erase(unique(q.begin(),q.end()),q.end());
      int z=q.size();
      for(int j=1;j<z;j++){
         if(q[j]-q[j-1]>1){
             q.push_back(q[j-1]+1);
         }
      }
      sort(q.begin(),q.end());
      mx=q.size();
      for(int j=1;j<=m;j++){
         int l=getid(ll[j]);
         int r=getid(rr[j]);
         updata(1,mx,l,r,1,j);
      }
      query(1,mx,1);
      cout<<ans<<endl;
   }
}