码迷,mamicode.com
首页 > 其他好文 > 详细

poj2528(线段树)

时间:2015-01-21 23:50:38      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

 

题目连接: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

 

poj2528(线段树)

标签:

原文地址:http://www.cnblogs.com/lienus/p/4240314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!