洛谷P3740 贴海报 线段树+染色问题

该博客主要介绍了如何使用线段树解决一道染色问题。通过在线段树节点增加color属性,并处理区间染色时的特殊情况,如颜色覆盖和区间查询。博主提到了离散化的重要性,并指出普通离散化可能导致的问题,给出了解决方案,即在离散化过程中保持相邻元素的相对位置。最后,提供了AC代码作为问题的解答。

标签:

  • 离散化
  • 线段树
  • 染色问题

思路:

  • 很容易想到线段树的区间修改。具体怎么处理呢?我们给线段树的节点增加一个color属性,找到对应的区间给他染色。那么会出现几个问题。
    1. 假设一共有10个节点,加入对1-3区间染色,那么经过了的1-10区间如何处理?

      我们将不能代表整个区间颜色的节点置为0。例如要对区间1-5染色,我们首先会经过1-10,然后递归来到1-5.这里我们只对1-5区间进行染色,而不对1-10进行染色操作。

    2. 同上10个节点,如果我先对1-10染色,再对1-5染色,怎么处理呢?

      对1-10,我们可以直接覆盖,1-10的颜色修改为1。接下来对1-5染色,首先来到1-10的节点,我们先将1-10spread一下,使得1-5变为1,6-10也变为1,然后使1-10的颜色标记为不存在。再将1-5的颜色记为2.

    3. 按照上面的做法做完后怎么计算颜色呢?

      颜色是覆盖的,每次涂色时,途径的节点都会改为真实颜色,所以最终我们直接单点查询所有的叶子节点,途径的节点都spread一下,保证查询到的是真实颜色。


注意事项:

  1. 询问只有2000个,而节点共有1e7个,因此我们考虑离散化。但是普通离散化会导致一个问题,例如对区间[1,4], [4,7], [7, 8]染色,离散化后[4,7]区间就没有颜色了!而[4-7]本身应该是有颜色的,归根结底,是因为[4,7]离散化成了[3,4]使得[3.4]之间没有节点。因此我们离散化时,不仅要知道他们的相对大小,还需要知道原数据是相邻还是相间的,如果相间的,我们不能离散化成相邻。所以我们直接对离散化集合扫一遍,遇到相间的,则在里面插入一个和端点相同的元素,保证离散化后,这两个数仍然相间。

AC代码

#include<cstdio>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;

const int maxn = 10000000 + 10;
const int maxm = 2000 + 10;

struct Node
{
   
   
    int l, r;
    int co;
};

Node tree[maxm * 4];

void build(int o, int l, int r)
{
   
   
    tree[o].l = l, tree[o].r = r;
    if (l == r)
        return;

    int mid = (l + r) / 2;
    build(o * 2, l, mid);
    build(o * 2 + 1, mid + 1, r);
}

void spread(int o)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值