CF1903D:Maximum And Queries 题解

D:

题意:给你一个数列a,Q个独立询问,每次操作给一个数加一,k次操作后最大化数列a的与值。

Solution:

因为是最大化与值,那高位和低位就不冲突了,贪心看每一位能不能成为答案的一部分。

我们用res表示已经确定成为答案的高位和,当我们考虑第 i 位能不能加入答案时,我们计算三种数的花费:

1:这个数为了让高位成为答案,低位已经被磨平了棱角(悲),那么花费就是 2i

2:这个数res的每一位它都有,也就是说低位还在,但是它第 i 位是0,需要补齐到第 i 位,那么低位就要被磨平了,花费是 2isum[i]sum[i] 是它低 i 位的和。

3:这个数很坚强,res的每一位它都有,第 i 位也有,不用管它,花费为 0。


第一种数从何而来,就是从第二种来,用 num 表示第一种数的个数,每一位如果被确定为答案,就把第二种数的数量加给 num。

发现第二种数与res有关,哪些高位被确定成答案,直接影响每一个数是否被磨平。我们设 f[res][i] 表示当前答案为 res 时高位它都有,但是第 i 位为零的数的数量,g[res][i] 表示这些数后 i 位的和。那么第二种数的花费就是:2if[res][i]g[res][i]

这一位计算完成后,num+=f[res][i]

当你以为设出状态来这题就结束时,却发现 f 数组和 g 数组怎么算成为了这道题的难点。其实也不难,只需要掌握一个小小的科技,就是子集DP。一看就懂的子集DP

对于每一个数,查看其为0的数位 i,res 作为 i 的高位的子集时,更新 f 数组和 g 数组,也就是说高位是超集,贡献向子集传递(高维后缀和)。

my submission

这题我们枚举res位数是从20开始向下的,但是答案可能很大,需要把那些答案大于20位的询问直接处理掉。


__EOF__

本文作者枫叶晴
本文链接https://www.cnblogs.com/maple276/p/17975317.html
关于博主:菜菜菜
版权声明:呃呃呃
声援博主:呐呐呐
posted @   maple276  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示