poj 2528 Mayor's posters (线段树+离散化)

/*
  离散化+线段树
  由于 数据的输入最大是 10000000 ,直接用开数组肯点会超,所以要将起离散话,
  首先 ,我们存储输入的边,将其离散化,后面的就和一般的线段树一样可。 
*/

#include<stdio.h>
#include<stdlib.h>
#define N 10040
struct node
{
    int l;
    int r;
}p[N*2];
struct color
{
    int l;
    int r;
    int c;
}q[N*8];
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int addre[N*4],sum,m,pos[N*4],vis[N];
void build(int x,int l,int r)
{
    q[x].l=l;
    q[x].r=r;
    q[x].c=0;
    if(l==r)return ;
    int mid=(l+r)/2;
    build(x*2,l,mid);
    build(x*2+1,mid+1,r);
}
int find(int x)//离散化后的查询
{
    int head=1,tail=m-1;
    while(head<=tail)
    {
        int mid=(head+tail)/2;
        if(addre[mid]==x)return mid;
        if(addre[mid]<x)head=mid+1;
        else
         if(addre[mid]>x)tail=mid-1;
    }
    return 0;
}
void change(int x,int l,int r,int color)
{
    if(q[x].l==l&&q[x].r==r)
    {
        q[x].c=color;
        return ;
    }
    if(q[x].c!=-1)//下分到子节点
    {
        q[x*2].c=q[x].c;
        q[x*2+1].c=q[x].c;
        q[x].c=-1;
    }
    int mid=(q[x].l+q[x].r)/2;
    if(r<=mid)change(x*2,l,r,color);
    else
    {
        if(l>mid)change(x*2+1,l,r,color);
        else
        {
            change(x*2,l,mid,color);
            change(x*2+1,mid+1,r,color);
        }
    }



}
void Get(int x,int l,int r)
{
    if(q[x].c==0)return ;
    if(q[x].c!=-1)
    {
        if(!vis[q[x].c])//避免重复计算
        {
            vis[q[x].c]=1;
            sum++;
        }
        return ;
    }
    int mid=(q[x].l+q[x].r)/2;
    if(r<=mid)Get(x*2,l,r);
    else
    {
        if(l>mid)Get(x*2+1,l,r);
        else
        {
            Get(x*2,l,mid);
            Get(x*2+1,mid+1,r);
        }
    }
}
int main()
{
    int T,n,i;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int k=1;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].l,&p[i].r);
            pos[k++]=p[i].l;
            pos[k++]=p[i].r;
        }
       qsort(pos,k,sizeof(pos[0]),cmp);

       addre[1]=pos[1];
        m=2;
       for(i=1;i<=k;i++)
       {
           if(pos[i]!=pos[i-1])
           {
               addre[m++]=pos[i];//离散化,用原来点的下标,来代替点,实现离散化
           }
       }
       build(1,1,m-1);
       for(i=1;i<=n;i++)
       {
           int l=find(p[i].l);//离散化,用原来点的下标,来代替点,实现离散化
           int r=find(p[i].r);
           change(1,l,r,i);
       }
       sum=0;
       for(i=0;i<=n;i++)vis[i]=0;
       Get(1,1,m-1);
       printf("%d\n",sum);
    }
}

  

posted @ 2012-04-13 20:25  Szz  阅读(128)  评论(0编辑  收藏  举报