POJ-25282:Mayor's posters

大意为给定一堆海报张贴顺序与张贴区间,求最后有几张海报没完全被挡住(来啊互相伤害啊!)。
由于数据太大而且海报都是几个点连在一起的,用以前的思路开树过于浪费,于是我们先将数据离散化(大概就是将一段连续的cut成一个点)再开线段树,由于我们写的是当一片区域没有完全cover的时候s++并且将其cober,所以注意cover的时候从后往前

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 10005

int cut[10000005],ml[maxn],mr[maxn],mm[maxn*2];

struct tr
{
    int l,r,cover;
}tree[maxn*8];

void build(int i,int ll,int rr)
{
    tree[i].l=ll;
    tree[i].r=rr;
    tree[i].cover=0;
    if(ll==rr) return;
    build(i*2,ll,(ll+rr)/2);
    build(i*2+1,(ll+rr)/2+1,rr);
}

int covered(int i,int ll,int rr)
{
    if(tree[i].cover==1) return 0;
    int res;
    if(tree[i].l==ll&&tree[i].r==rr) {tree[i].cover=1;return 1;}
    else if(ll>(tree[i].r+tree[i].l)/2) res=covered(i*2+1,ll,rr);
    else if(rr<=(tree[i].r+tree[i].l)/2) res=covered(i*2,ll,rr);
    else
    {
        int a=covered(i*2+1,(tree[i].r+tree[i].l)/2+1,rr);
        int b=covered(i*2,ll,(tree[i].r+tree[i].l)/2);
        if(a==1||b==1) res=1;
    }
    if(tree[i*2].cover==1&&tree[i*2+1].cover==1) tree[i].cover=1; //向上合并
    return res;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,i,k=0,s=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++) scanf("%d%d",&ml[i],&mr[i]);
        for(i=1;i<=n;i++) {mm[++k]=ml[i];mm[++k]=mr[i];}
        sort(mm+1,mm+k+1);
        k=unique(mm+1,mm+1+k)-mm-1; //将数据排序并减去重复的
        for(i=1;i<=k;i++) cut[mm[i]]=i; //离散化
        build(1,1,k);
        for(i=n;i>=1;i--) {s+=covered(1,cut[ml[i]],cut[mr[i]]);}
        printf("%d\n",s);
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值