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);

    }

}

  

你可能感兴趣的:(post)