poj2528(线段树+区间离散)

题意:那个城市里要竞选市长,然后在一块墙上可以贴海报为自己拉票,每个人可以贴连续的一块区域,后来帖的可以覆盖前面的,问到最后一共可以看到多少张海报。
思路:一看就知道是线段树,只是说要利用到离散化,也不是那么的难,当然注意,有的离散化错误也ac了......当然,在最后没必要还一个个去询问是否覆盖,直接开个标记数组,询问到一个区间只有一个覆盖值,然后进行标记就可以。

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 100005
struct node
{
    int ll,rr;
    int num;
    int cnt;
}tree[8*M];
int s[4*M][2],t[4*M];
int xx[4*M];
int ans=0,flag=0;
void creat(int i,int l,int r)
{
    tree[i].ll=l;
    tree[i].rr=r;
    tree[i].cnt=0;
    tree[i].num=0;
    int mid=(l+r)/2;
    if(l==r)
    {
        //tree[i].num=0;
        return;
    }
    creat(i*2,l,mid);
    creat(i*2+1,mid+1,r);
}
void updata(int i,int left,int right,int k)
{
    if(tree[i].ll==left&&tree[i].rr==right)
    {
        tree[i].cnt=1;
        tree[i].num=k;
        //if(k==2)
        //printf("%d  %d\n",left,right);
        return;
    }
    if(tree[i].cnt==1)
    {
        tree[i*2].cnt=1;
        tree[i*2+1].cnt=1;
        tree[i*2].num=tree[i].num;
        tree[i*2+1].num=tree[i].num;
        tree[i].cnt=2;
        tree[i].num=0;
    }
    int mid=(tree[i].ll+tree[i].rr)/2;
    if(mid>=right)   updata(i*2,left,right,k);
    else  if(mid<left)   updata(i*2+1,left,right,k);
    else
    {
        updata(i*2,left,mid,k);
        updata(i*2+1,mid+1,right,k);
    }
    if(tree[i*2].cnt==1&&tree[i*2+1].cnt==1&&tree[i*2].num==tree[i*2+1].num)
    {
        tree[i].cnt=1;
        tree[i].num=tree[i*2].num;
    }

    else   tree[i].cnt=2;
    //printf("updata\n");
}
void quest(int i)
{
    //if(k==1)
    //printf("%d  %d  %d  %d  %d\n",tree[i].ll,tree[i].rr,tree[i].cnt,tree[i].num,k);
    if(tree[i].cnt==1)
    {
        xx[tree[i].num]=1;
        return;
    }
    if(tree[i].ll==tree[i].rr)
    return;
    //if(flag==1)
    //return;
    if(tree[i].cnt==0)
    return;
    quest(i*2);
    quest(i*2+1);

   // printf("quest\n");
}
int erfen(int ll,int rr,int num)
{
    while(ll<=rr)
    {
        int mid=(ll+rr)/2;
        if(t[mid]>num)
        rr=mid-1;
        else
        ll=mid+1;
       // printf("erfen\n");
    }
    return rr;
}
int main()
{
    int text;
    scanf("%d",&text);
    while(text--)
    {
        int n;
        scanf("%d",&n);
        //creat(1,1,3*n);
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&s[i][0],&s[i][1]);
            t[cnt++]=s[i][0];
            t[cnt++]=s[i][1];
        }
        sort(t,t+cnt);
        int cnt1=1;

        for(int i=1;i<cnt;i++)
        if(t[i]!=t[i-1])   t[cnt1++]=t[i];

        for(int i=cnt1-1;i>0;i--)
        if(t[i]!=t[i-1]+1)   t[cnt1++]=t[i-1]+1;
        sort(t,t+cnt1);
        for(int i=cnt1;i>0;i--)
        t[i]=t[i-1];
        creat(1,1,cnt1+5);
        for(int i=1;i<=n;i++)
        {
            int ll=1,rr=cnt1;
            int tmp=erfen(ll,rr,s[i-1][0]);
            int tmp1=erfen(ll,rr,s[i-1][1]);
            //tmp;
            //tmp1;
            //printf("%d %d\n",tmp,tmp1);
            updata(1,tmp,tmp1,i);
        }
        ans=0;
        memset(xx,0,sizeof(xx));
        quest(1);
        for(int i=1;i<=n;i++)
        if(xx[i]==1)
        ans++;
        printf("%d\n",ans);
    }
    return 0;
}

 

 

 

posted @ 2013-11-22 21:17  紫忆  阅读(2397)  评论(0编辑  收藏  举报