POJ 2528 Mayor's posters 【线段树(区间为节点问题)】

传送门
// 首先说下这道题数据应该是有问题的… 推荐这道题 题意一模一样, 但是这道题更严谨一点.
就是给出n个区间的覆盖信息, 问最后有多少张海拔被看见.

很明显的线段树区间问题, 以一段区间为线段树的一个节点, 然后做区间更新和区间覆盖, 由于区间信息较大, 要进行离散化,这道题唯一有坑的就是它会出现(1, 1), (2, 2)这种长度为0的数据(那里说贴海报怎么可能贴长度为0的), 但是这道题就是有, wa的原因可能就是因为这样导致建的区间长度过短, 所以我们就把左端点–,这样我试着交了一发然后就A了….
但是这样是不对了, 因为有数据可以hack:
1
3
5 6
4 5
6 8
这样就会输出2, 很显然是3呀, 所以这道题还是随便做做就好, 还是做我上面推荐的那道题就好了.

AC Code

const int maxn = 2e4 + 5;
int ans = 0;
int n,m;
int a[maxn],vis[maxn];
vector<int >v;
struct node
{
    int tl,tr; ll val,lazy;
    void fun(ll tmp){
        lazy = tmp;
        val = tmp;
    }
}tree[maxn*4];

struct edge
{
    int l,r;
}q[maxn];

void build(int id,int l,int r)
{
    tree[id].tl = l; tree[id].tr = r;
    tree[id].val = tree[id].lazy = 0;
    if(l+1 == r){
        return ;
    }
    int mid = (l+r) >> 1;
    build(id<<1,l,mid);
    build(id<<1|1,mid,r);
}

void pushdown(int id)
{
    if(tree[id].lazy){
        tree[id<<1].fun(tree[id].lazy);
        tree[id<<1|1].fun(tree[id].lazy);
        tree[id].lazy = 0;
    }
}

void update(int id,int ul,int ur,int val)
{
    int l = tree[id].tl,r = tree[id].tr;
    if(ul <= l && r <= ur){
        tree[id].lazy = val;
        tree[id].val = val;
        return ;
    }
    pushdown(id);
    int mid = (l+r) >> 1;
    if(ul < mid ) update(id<<1,ul,ur,val);
    if(ur > mid ) update(id<<1|1,ul,ur,val);
}

void query(int id,int ql,int qr)
{
    int l = tree[id].tl,r = tree[id].tr;
    if(l + 1 == r){
        if(!vis[tree[id].val]){
            vis[tree[id].val] = 1;
            ans++;
        }
        return ;
    }
    pushdown(id);
    int mid = (l+r) >> 1;
    if(ql < mid) query(id<<1,ql,qr);
    if(qr > mid) query(id<<1|1,ql,qr);
}

int getid(int x)
{
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

void solve()
{
    scanf("%d",&n);
    v.clear();
    for(int i = 1 ; i <= n ; i ++) {
        scanf("%d%d",&q[i].l,&q[i].r);
        q[i].l--;
        v.push_back(q[i].l);
        v.push_back(q[i].r);
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    build(1, 1, v.size());
    for(int i = 1 ; i <= n ; i ++) {
        int l = getid(q[i].l);
        int r = getid(q[i].r);
        update(1, l, r, i);
    }
    Fill(vis,0);
    vis[0] = 1; ans = 0;
    query(1,1,v.size());
    printf("%d\n",ans);
}

你可能感兴趣的:(线段树/RMQ/扫描线)