题意:
将一段长为L的板子染色,板子可分为编号为1,2,3...L的L段,总共有O次操作,操作有两种:1.将A到B区间染为颜色C 2.询问A到B区间有多少种颜色。颜色从1到T编号,不超过30种。
?
思路:1.由于颜色不超过30种,所以可以考虑位运算,每一位代表一种颜色,一个32位整数就可以存储所有的颜色状态。
2.对于操作一,就是区间更新操作,需要用lazy操作,当需要更新子节点时才往下更新,把子节点的颜色染为lazy的颜色(即上一个节点染得颜色),并且把lazy下移。(代码中的pushdown函数),更新子节点后,用pushup函数将子节点的染色状态更新到父节点。
3.对于操作二,就是区间询问,也用到lazy操作,需要询问子节点时使用pushdown函数将子节点染色,然后查询到目标区间后,返回目标区间的染色状态(一个32位整数),最后将所查区间的染色状态按位与,二进制中1的个数即所用颜色的数目。
易错点:
1.注意使用lazy操作,不然超时。
2.建树的时候也要用pushup操作更新父节点
3.在pushup函数中,是把左右子节点的染色状态按位或,而pushdown函数中,是直接将父节点的上次所染颜色更新到子节点。原因是pushup是将子区间并起来,而pushdown是区间染色。
4.查询的时候也要使用pushdown,因为有可能所查子节点状态未被更新。
5.A可能大于B
代码:
?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include