poj2528(线段树)

 

题目连接:http://poj.org/problem?id=2528

题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报

分析:离散化+线段树,这题因为每个数字其实表示的是一个单位长度,因此离散化后的每个点如果相邻数字间距大于1的话,得在其中加上任意一个数字。

否则 如 [1 10] [1 3] [5 10]这组数据能看见3种海报,而离散化后[1,3,5,10]对应[1,2,3,4],更新[1,2]再更新[3,4]就能看见两种海报了。所以离散化应为[1,2,3,4,5,9,10].

#pragma comment(linker,"/STACK:102400000,102400000")

#include <cstdio>

#include <cstring>

#include <string>

#include <cmath>

#include <iostream>

#include <algorithm>

#include <queue>

#include <cstdlib>

#include <stack>

#include <vector>

#include <set>

#include <map>

#define LL long long

#define mod 1000000007

#define inf 0x3f3f3f3f

#define N 200010

#define FILL(a,b) (memset(a,b,sizeof(a)))

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

using namespace std;

bool has[N];

int le[N],ri[N];

int col[N<<2],X[N];

int ans;

int bin(int key,int n,int a[])

{

    int l=0,r=n-1;

    while(l<=r)

    {

        int m=(l+r)>>1;

        if(a[m]==key)return m;

        if(a[m]<key)l=m+1;

        else r=m-1;

    }

}

void Pushdown(int rt)

{

    if(col[rt]!=-1)

    {

        col[rt<<1]=col[rt<<1|1]=col[rt];

        col[rt]=-1;

    }

}

void update(int L,int R,int c,int l,int r,int rt)

{

    if(L<=l&&r<=R)

    {

        col[rt]=c;

        return;

    }

    Pushdown(rt);

    int m=(l+r)>>1;

    if(L<=m)update(L,R,c,lson);

    if(m<R)update(L,R,c,rson);

}

void query(int l,int r,int rt)

{

    if(l==r)

    {

        if(col[rt]!=-1)

        {

            if(!has[col[rt]])ans++;

            has[col[rt]]=true;

        }

        return;

    }

    Pushdown(rt);

    int m=(l+r)>>1;

    query(lson);

    query(rson);

}

int main()

{

    int T,n;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d",&n);

        int nn=0;

        for(int i=1;i<=n;i++)

        {

            scanf("%d%d",&le[i],&ri[i]);

            X[nn++]=le[i];

            X[nn++]=ri[i];

        }

        sort(X,X+nn);

        int m=1;

        for(int i=1;i<nn;i++)

            if(X[i]!=X[i-1])X[m++]=X[i];

        for(int i=m-1;i>0;i--)

            if(X[i]!=X[i-1]+1)X[m++]=X[i-1]+1;

        sort(X,X+m);

        FILL(col,-1);

        for(int i=1;i<=n;i++)

        {

            int l=bin(le[i],m,X);

            int r=bin(ri[i],m,X);

            update(l+1,r+1,i,1,m,1);

        }

        ans=0;FILL(has,false);

        query(1,m,1);

        printf("%d\n",ans);

    }

}
View Code

 

你可能感兴趣的:(poj)