您的位置:首页 > 其它

【笔记】染色问题的俩解法

2017-10-11 19:08 926 查看

染色问题题意概要

给定一个长度为n的数字序列,有m次对[Li,Ri]的涂色(或其他修改),求最后的序列


其实这种题最突出的特征是覆盖,即后面的操作会覆盖前面的操作,所以若一段区间被修改多次,取最后一次修改即可;

一:线段树做法

其实这种题一看,用线段树,再一看,还是线段树,耐着性子看最后一遍,仍是线段树。所以就开始码吧!

其实呢这题用普通线段树有一点麻烦了,因为这种题同一点标记只会有一个,要那区间l和r干啥嘞,zkw线段树那么好用,用zkw线段树可以优化时间,最后从上往下走(千万别告诉zkw我把他的线段树从上往下走了),一旦找到标记,看看这个区间的叶子节点数k,直接输出k个标记即可

二:并查集做法

这种题用线段树还是有一丢丢浪费,即便用zkw,O(nlogn)的复杂度还是在那里滴,有一个神奇的线性做法,其实感性地想一想(我已经分不清理性还是感性了) 若是从后往前时光把m个操作反过来,先操作m,m-1,……,1然后已经染色过的点就不操作了。

理想很远大,但操作就不简单了

操作不简单?

操作很简单

既然操作过这个区间就不必再操作了,那么为了达到线性时间,在下一次询问时就
4000
必须直接跳过其。

那么可不可以直接将区间左端点直接指向右端点呢?
当然不可以。举个小栗子:若先修改[3,5]再操作[1,6],那在最后输出路径的时候就会忽略[3,5]。


有一个解决方法,就是将该区间所有节点都指向右边的节点,并将区间左端点的左边的点飞跃整个区间,指向右端点的右边的点,这样在下一次访问到区间后就会直接飞过整个区间。

再举个栗子:当修改了[3,5]后

2->6->空白

3->4->5->颜色

再修改[1,6]后

1->2->6->颜色

3->4->5->颜色

我们十分惊奇的发现,前面拜访过的区间之后不会拜访了,所以无论有多少次修改,时间永远都是线性的(包括最后的输出),最后输出使用棒棒的路径压缩,又是线性的 \(^o^)/~ 庶民的胜利
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: