POJ 2528 Mayor's posters

<strong><span style="font-size:24px;">大概意思:在一个墙上贴海报,每一个海报在墙上占据x~y的位置,按照输入顺序贴海报,问最后墙上能看见几张海报。</span></strong>

Sample Input

1
5
1 4
2 6
8 10
3 4
7 10

Sample Output

4
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#define MAXN 10000010
using namespace std;

int n,ans;
int p[21000];
int vis[10010];
struct point{
    int x,y;
}pp[11000];
struct node{
    int l,r;
    int flag;//海报
}a[MAXN<<2];

void build(int l,int r,int index){
    a[index].l = l;
    a[index].r = r;
    a[index].flag = 0;//初始化为0,代表没有海报
    if(l == r){
        return ;
    }
    int mid = (l+r)>>1;
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
}

void updata(int l,int r,int index,int val){
    if(l <= a[index].l && r >= a[index].r){
        a[index].flag = val;
        return ;
    }
    if(a[index].flag){
        /*该(a[index].l~a[index].r)位置之前有海报,
          需要把该位置清0,然后向下标记。
        */
        a[index<<1].flag = a[index].flag;
        a[index<<1|1].flag = a[index].flag;
        a[index].flag = 0;
    }
    int mid = (a[index].l+a[index].r)>>1;
    if(l <= mid){
        updata(l,r,index<<1,val);
    }
    if(r > mid){
        updata(l,r,index<<1|1,val);
    }
}

void query(int index){
    if(a[index].flag){
        if(vis[a[index].flag] == 0){
            ans++;
            vis[a[index].flag] = 1;
        }
        return ;
    }
    query(index<<1);
    query(index<<1|1);
    return ;
}

int main(){
    int T;
    int x,y;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        int l = 0;
        for(int i = 0; i < n; i++){
            scanf("%d %d",&pp[i].x,&pp[i].y);
            p[l++] = pp[i].x;
            p[l++] = pp[i].y;
        }
        //数据离散化
        sort(p,p+l);
        int len = unique(p,p+l)-p;
        build(1,len,1);
        for(int i = 0; i < n; i++){
            pp[i].x = lower_bound(p,p+len,pp[i].x)-p+1;
            pp[i].y = lower_bound(p,p+len,pp[i].y)-p+1;
            updata(pp[i].x,pp[i].y,1,i+1);
        }
        ans = 0;
        memset(vis,0,sizeof(vis));
        query(1);
        printf("%d\n",ans);
    }
    return 0;
}



                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值