poj 2528

来源:互联网 发布:代购记账软件 编辑:程序博客网 时间:2024/05/21 17:17

     经典的线段树+离散化。我还不会离散化,学习了。

     本题的线段区间很大,如果直接模拟不是mle就是re,但实际插入的点很少,所以要离散化每个插入的区间,然后对离散化后的区间构造线段树。所谓离散化,个人的理解是自行构造一个函数,使得原数轴上的区间与自定义的数轴的区间形成一一对应的关系,从而压缩了整个区间,减少空间复杂度。这里只要跟着我的代码,用题中的样例模拟一下就可以懂的了。

      以下是代码:

 

  1. #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=20001;
  2. struct Tree
    {
     int col;
     int l,r;
    }T[3*M];
  3. struct Line
    {
     int li,num;
     bool operator <(const Line a)const{
      return li<a.li;
     }
    }line[M];
    int rec[M][2];
    bool vis[M];
    int n,ans;
  4. void build(int l,int r,int p)
    {
     T[p].l=l;
     T[p].r=r;
     T[p].col=0;
     if(l==r) return ;
     int mid=(l+r)>>1;
     build(l,mid,p<<1);
     build(mid+1,r,p<<1|1);
    }
  5. void update(int l,int r,int x,int p)
    {
     if(T[p].l==l && T[p].r==r)
     {
      T[p].col=x;
      return ;
     }
     if(T[p].col>0 && T[p].col!=x)
     {
      T[p<<1].col=T[p<<1|1].col=T[p].col;
      T[p].col=0;
     }
     int mid=(T[p].l+T[p].r)>>1;
     if(r<=mid) update(l,r,x,p<<1);
     else if(l>mid) update(l,r,x,p<<1|1);
     else
     {
      update(l,mid,x,p<<1);
      update(mid+1,r,x,p<<1|1);
     }
    }
  6. void find(int p)
    {
     if(T[p].col>0)
     {
      if(!vis[T[p].col])
      {
       ans++;
       vis[T[p].col]=1;
      }
      return;
     }
     find(p<<1);
     find(p<<1|1);
    }
  7. int main()
    {
    // freopen("in.txt","r",stdin);
     int T;
     scanf("%d",&T);
     while(T--)
     {
      scanf("%d",&n);
      int i;
      for(i=0;i<n;i++)
      {
       scanf("%d%d",&rec[i][0],&rec[i][1]);
       line[2*i].li=rec[i][0];
       line[2*i].num=-(i+1);
       line[2*i+1].li=rec[i][1];
       line[2*i+1].num=i+1;
      }
      sort(line,line+2*n);
      int temp=line[0].li,tp=1;
      for(i=0;i<2*n;i++)
      {
       if(line[i].li!=temp)
       {
        tp++;
        temp=line[i].li;
       }
       if(line[i].num<0)
       {
        rec[-line[i].num-1][0]=tp;
       }
       else
       {
        rec[line[i].num-1][1]=tp;
       }
      }
      build(1,tp,1);
      for(i=0;i<n;i++)
      {
       update(rec[i][0],rec[i][1],i+1,1);
      }
      memset(vis,0,sizeof(vis));
      ans=0;
      find(1);
      printf("%d/n",ans);
     }
     return 0;
    }
原创粉丝点击