【题解】codeforces 1209 - problem G2. Into Blocks (hard version)

链接

做法

感谢 @newbiegcz 的指导
做法和题解是一样的,然而英文太烂没有看懂。看了cz_xuyixuan的才看懂。后面维护方法和他略有不同

要找分界点:分段后,每段包含其中的所有颜色的所有出现位置
首先:一个颜色只考虑其两端 [ L i , R i ] [L_i,R_i] [Li,Ri],分界点不能在这个区间中间。每个颜色会删去在 [ L i , R i ) [L_i,R_i) [Li,Ri)的分界点,剩下的就是合法分界点(被删除次数为 0 0 0的位置后)
分出每一段后,求出每段颜色出现次数最大值, 答 案 = n − 每 段 最 大 值 求 和 答案 = n - 每段最大值求和 =n
带修改的情况用线段树维护这个覆盖次数(被删除的次数),为 0 0 0则是一个合法的分界点。而注意到在顶层n后面一定是一个合法的分界点。故只需要记录最小值,默认每一层的最小值位置后就是合法分界点。合并的时候讨论一下即可这样就只用一个线段树搞定了!(这种做法学习自@newbiegcz的代码)
对于修改,经典的做法是看成对两种颜色的删除和插入。修改一种颜色时,也是先在线段树中删除这种颜色,再修改,再插入。这样非常好写!

#include<bits/stdc++.h>
using namespace std;
#define PB push_back
#define lowbit(x) (x&(-x))
#define MP make_pair
#define fi first
#define se second
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
#define rep(i,l,r) for (int i = l ; i <= r ; i++)
#define down(i,r,l) for (int i = r ; i >= l ; i--)
#define fore(i,x) for (int i = head[x] ; i ; i = e[i].next)
#define SZ(v) (int)v.size()

typedef long 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值