[gym 225975L] Гирлянда
思路
题意
每次操作一种颜色使其翻转, 求极长亮灯区间个数
首先进行简单转化, 不难发现相邻的同颜色灯泡是没什么意义的, 因此进行缩点
现在变成了这样一种形式

不难发现极大亮灯区间的计算方式
假设当前有 \(u\) 个亮着的灯, 其中有 \(w\) 条边连接了两个两者的灯\((\)因为先前的缩点, 一定是两个不同的颜色的灯\()\)
那么极大亮灯区间的个数为 \(u - w\) 个
部分分(出题人提示)
确定颜色数量
不难发现可以预处理出每两种颜色之间的边有多少条, 一次修改只需要枚举颜色做到
然后我把这个做了之后, 竟然没有想到最简单的暴力错失了想到根号分治的机会
你发现这是个数少的处理方式, 就应该去想用大小处理问题的方式
不难发现, 如果一种颜色的灯泡个数少, 我们可以枚举其每个灯泡, 判断连边是否有效即可
现在用逻辑化的语言解释上面的内容
设立阈值 \(B\)
不妨设 \(cnt_k\) 为颜色 \(k\) 的灯泡个数
- 假设 \(cnt_i \leq B\) , 我们称之为小颜色
- 假设 \(cnt_i \geq B\) , 我们称之为大颜色
那么我们可以这样思考
- 当前修改小颜色
- 枚举小颜色的连边, 判断连边是否有效, 复杂度 \(\mathcal{O} (B)\)
 
- 当前修改大颜色
- 大颜色和大颜色之间的连边
 注意到直接枚举大颜色的连边复杂度不好, 考虑到大颜色个数少, 用个数解决问题
 同特殊性质, 两两大颜色之间处理连边个数, 复杂度 \(\mathcal{O} (\frac{n}{B})\)
- 大颜色和小颜色之间的连边
 逆向思考, 处理小颜色的时候, 预处理其连边的大颜色开关灯的贡献
 具体的, 如果当前小颜色连向了大颜色, 那么大颜色开灯的贡献就是亮灯有连边小颜色的边数
 
- 大颜色和大颜色之间的连边
总结
根号分治的技巧
个数少, 用个数处理问题
        个数多, 代表大小少, 用大小处理问题
大小少, 用大小处理问题
        大小大, 代表个数少, 用个数处理问题
如果题目中出现了 个数少/大小少, 那么我们推 大小少/个数少 的做法

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号