题目来源
题目大意
本题的物品对答题并没有任何实际作用,完全可以忽略不计
有 n n n个套餐,要求套餐的价格严格递增。
有 Q Q Q次操作
1 r c:把第 r r r个套餐价格的二进制为异或 1 1 1
2:询问套餐的价格的最小值
若某个套装价格的二进制中某一位为 1 1 1,那么这一位定价可以为 1 1 1或者 0 0 0,否则这一位必须为 0 0 0
比赛情况
比赛的时候先打了其他两道题目,最后用两个小时来做这到题目。
这道题目要用数据结构来维护每个套装里二进制为 1 1 1位置,可以用动态开点线段树或者平衡树。
我这道题用了 s e t set set做,我昨晚还复习到了 s e t set set的用法,嗷呜
说实话用 s e t set set实现这道题代码挺短的,不过我在用 s e t set set时细节处理让我调了很久,嗷
结果比赛的代码出现了一些细节错误,直接Wa 52,考后用了 10 10 10分钟就调出来了,呜
这一方面是我对 s e t set set的不熟悉,另一方面是我没有具体去分析边界的影响
后来做完去看标准思路,标准思路的核心部分和我的思路差不多,但标准思路的实现更繁琐
详细思路
The way I think
因为套餐的价格严格递增,所以要让总价格最小,就得让每一个套餐尽可能的小
观察数据范围发现 m m m特别大,不能直接把每一位的为 1 1 1为 0 0 0情况直接存下来
对每一个套餐开一个数据结构,保存这个套餐价格二进制可以为 1 1 1的位置,并使其有序
对于每个查询,从第一个套餐开始枚举到最后一个套餐
记录上一个套餐价格情况 L a s t Last Last(里面存的上一个套餐最终价格二进制为 1 1 1的位置,同样要用数据结构来维护)
当前的最小解 H H H,辅助操作数据结构 s s s,第 i i i套餐价格的二进制位可以为 1 1 1的位置存储到 t o t [ i ] tot[i] tot[i]里
同时 t o t [ i ] tot[i] tot[i]的尾部开始遍历数据(即从大到小遍历),并定义一个指针指向 L a s t Last Last的尾部
如果当前 t o t [ i ] tot[i] tot[i]大于指针所处的 L a s t Last Last,那么用 s s s更新 H H H,再把当前 t o t [ i ] tot[i] tot[i]的值放进 H H H里,这样的 H H H必然当前最小且合法
如果当前 t o t [ i ] tot[i] tot[i]等于指针所处的 L a s t Last Last,把当前 t o t [ i ] tot[i] tot[i]的值放进 s s s里,这样能使 s s s和 H H H更贴近 L a s t Last Last
如果当前 t o t [ i