Mayor's posters

题目

有一面墙,现在有M张海报要贴,海报的高度和墙的高度一样,每张海报会给出区间范围[l,r],问最终墙上可见的海报有多少张?
墙的宽度:

分析

首先这题的墙的范围很大,所以必须离散化,然后在离散化之后的数据上建立线段树。

要点

这题对于染色后连续的区间[l,r]有可能离散化会在建立线段树的时候分开,所以最好在区间[l,r]中间加一个点[l,mid,r],这样如果染色[l,r],就会pushdown到[l,mid],[mid+1,r]。 但是数据比较谁水,不加也能过

AC代码(无插点)插点也很简单

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const ll maxn = 1e5+10;

ll T,M;
set<int> st;
struct node{
    ll l,r,tag;//tag: 海报标记
}tr[4*maxn];
int arr[1000010],tail;//用于离散化
int op[1000010][2];
void pushup(ll u){
    node &fa = tr[u],&L = tr[u*2],&R = tr[u*2+1];
    if(L.tag == R.tag){//海报往上传递
        fa.tag = L.tag;
    }else{
        fa.tag = 0;
    }
}
void pushdown(ll u){
    node &fa = tr[u],&L = tr[u*2],&R = tr[u*2+1];
    if(fa.tag){ //海报往下覆盖
        L.tag = fa.tag;
        R.tag = fa.tag;
    }
}
void build(ll u,ll l,ll r){
    if(l == r){
        tr[u] = {l,r,1};
    }else{
        tr[u] = {l,r};
        ll mid = (l+r)>>1;
        build(u*2,l,mid);
        build(u*2+1,mid+1,r);
        pushup(u);
    }
}
void modify(ll u,ll l,ll r,ll tag){
    if(tr[u].l>=l && tr[u].r<=r){
        tr[u].tag = tag;
    }else{
        pushdown(u);
        ll mid = tr[u].l+tr[u].r>>1;
        if(l<=mid) modify(u*2,l,r,tag);
        if(r>mid) modify(u*2+1,l,r,tag);
        pushup(u);
    }
}
void query(ll u,ll l,ll r){
    if(tr[u].tag){
        st.insert(tr[u].tag);
    }else{
        query(u*2,l,r);
        query(u*2+1,l,r);
    }
}

int ind(int x){
    return lower_bound(arr,arr+tail,x)-arr + 1;//因为线段树管理的下标我是1开始的,所以+1
}
int main(){
    cin>>T;
    while(T--){
        st.clear();
        tail = 0;
        scanf("%lld",&M);
        for(int i = 0;i<M;i++){
            scanf("%d%d",&op[i][0],&op[i][1]);
            arr[tail++] = op[i][0];
            arr[tail++] = op[i][1];
        }
        sort(arr,arr+tail);
        tail = unique(arr,arr+tail)-arr; 
        build(1,1,tail);
        int tag = 1;
        for(int i = 0;i<M;i++){
            modify(1,ind(op[i][0]),ind(op[i][1]),tag); 
            tag++;
        }
        query(1,1,tail);
        cout<<st.size()<<endl;
    }

    return 0;
}