POJ-2528 Mayor's posters

题目链接

题意:

每张海报覆盖了区间\([l_i,r_i]\)。现在按顺序贴\(n\)张海报,求到最后还能看到几张海报

分析:

首先不是问能看到几张不同的海报片段,样例中有\(5\)个海报片段,但是只有\(4\)张海报。

我们可以先把所有的海报贴上去,线段树记录区间是被第几张海报覆盖的。如果有多张海报,则\(cov = 0\)

然后我们在对第\(i\)张海报的区间进行查询,看有无某一个小区间段能被看见,即\(cov = i\)

剪枝:

  1. cov != 0 && cov != i return 0;
  2. cov = v return 1;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;

const int N = 1e5 + 10;
int n;
int L[N],R[N];
int lsh[N << 1],cnt;

#define mid ((l + r) >> 1)
#define ls (nod << 1)
#define rs (nod << 1 | 1)
#define lson ls,l,mid
#define rson rs,mid + 1, r

struct Node{
    int lv,rv,cov;
}t[N << 3];
void pushup(int nod){
    t[nod].lv = t[ls].lv; t[nod].rv = t[rs].rv;
}
void pushdown(int nod){
    if(t[nod].cov == 0) return ;
    t[ls].lv = t[ls].rv = t[rs].lv = t[rs].rv = t[nod].cov;
    t[ls].cov = t[rs].cov = t[nod].cov;
    t[nod].cov = 0;
}
void update(int nod,int l,int r,int ll,int rr,int v){
    if(l > rr || r < ll) return ;
    if(ll <= l && r <= rr){
        t[nod].cov = t[nod].lv = t[nod].rv = v;
        return ;
    }
    pushdown(nod);
    update(lson,ll,rr,v); update(rson,ll,rr,v);
    pushup(nod);
}
bool query(int nod,int l,int r,int ll,int rr,int v){
    if(l > rr || r < ll) return 0;
    if(t[nod].cov != 0 && t[nod].cov != v) return 0;
    if(t[nod].cov == v) return 1;
    if(l == r) return t[nod].cov == v;
    pushdown(nod);
    return query(lson,ll,rr,v) || query(rson,ll,rr,v);
}

int main(){
    int T; scanf("%d",&T);
    while(T --){
        scanf("%d",&n);
        
        cnt = 0;
        for(int i = 1; i <= n; ++ i) scanf("%d%d",&L[i],&R[i]), lsh[++ cnt] = L[i], lsh[++ cnt] = R[i];
        
        sort(lsh + 1, lsh + cnt + 1); cnt = unique(lsh + 1, lsh + cnt + 1) - lsh - 1;
        for(int i = 1; i <= n; ++ i){
            L[i] = lower_bound(lsh + 1, lsh + cnt + 1, L[i]) - lsh;
            R[i] = lower_bound(lsh + 1, lsh + cnt + 1, R[i]) - lsh;
            
            update(1,1,cnt,L[i],R[i],i);
        }
        int ans = 0;
        for(int i = 1; i <= n; ++ i){
            if(query(1,1,cnt,L[i],R[i],i)) ++ ans;
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zzhzzh123/p/13399466.html