1004F.Sonya and Bitwise OR(毒瘤线段树+分治思想)
作者:互联网
性质:
对一个序列的或前缀和是单调不降的,每次变化至少增加一个二进制位
同时一段区间内发生变化的位置数量<=20(log值域)
那么就可以对线段树上的每个节点维护这样的一组信息:
区间内前缀或发生变化的位置以及它在区间内的前缀或
区间内后缀或发生变化的位置以及它在区间内的后缀或
一个区间内的答案数量,就是它两个子区间的答案加上区间本身的答案。
区间本身的答案计算,就是枚举左区间后缀和和右区间前缀和的每个位置,就是用双指针的方法O(20)求解。因为最多20个点。
现在考虑区间合并。
两个区间的合并,先保留左区间前缀或的变化位置,然后枚举右区间前缀或的每个位置,如果不变就跳过,如果变化就把位置加到父节点的前缀或变化位置里。
同理,保留右区间的后缀或变化位置,然后枚举左区间后缀或的每个位置,如果不变就跳过,如果变化就把位置加到父节点的后缀或变化位置里。
每个区间的答案就是合并后的新答案加上它的两个子区间的答案。
现在考虑区间查询。
查询一个区间,返回一个结构体,包含前缀、后缀、答案。
用刚刚的方法合并两个子查询,并返回上一层函数即可。
现在考虑单点修改。
修改一个点,会影响它的所有父节点,对所有父节点的前后缀变化点暴力修改就完事了。
时间复杂度O(20logn)。
总的时间复杂度O(20nlogn)。
感觉这题是我目前遇到的线段树区间维护天花板了。妥妥的银牌题往上,无论是代码难度还是思维难度。
代码之后有空补,有点太晚了,还要肝一堆作业。
标签:前缀,后缀,位置,Bitwise,Sonya,答案,区间,节点,1004F 来源: https://www.cnblogs.com/zhanglichen/p/14815745.html