登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
博客
发1篇日志+1圆
记录
发1条记录+2圆币
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
VIP网盘
VIP申请
网盘
联系我们
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
科技
›
【题解】CF2077B Finding OR Sum
【题解】CF2077B Finding OR Sum
[ 复制链接 ]
搜娲瘠
2025-6-8 22:23:20
本文发布于博客园和洛谷,若您在其他平台阅读到此文,请前往博客园获得更好的阅读体验。
跳转链接:https://www.cnblogs.com/TianTianChaoFangDe/p/18771334。
思路
关于此题,我们首先对 \(n | x\) 变一下形,\(n | x = n + (x \& \sim n)\),也就是把 \(n\) 和 \(x\) 同时为 \(1\) 的位在 \(x\) 中删掉,这样的话,为 \(1\) 的位要么在 \(n\),要么在 \(x\),因此我们可以得出 \((x \& \sim n) + (y \& \sim n) = (n | x) + (n | y) - 2 \times n\)。
我们要得到 \((m | x) + (m | y)\) 的值,只需要把每一位上 \(x\) 和 \(y\) 的 \(1\) 的出现数量情况找出来,再根据 \(m\) 的每一位是 \(1\) 还是 \(0\) 来模拟或运算以及位运算即可。
那么我们如何在两次询问的情况下,把每一位的 \(1\) 的出现数量找出来呢?
我们注意到,在二进制位的情况下相加,当前位为第 \(i\) 位,如果第 \(i + 1\) 位和 \(i - 1\) 位都是 \(0\),则两个数的第 \(i\) 位相加只会有这两种情况:
两个 \(1\):第 \(i + 1\) 位为 \(1\),第 \(i\) 位为 \(0\)。
两个 \(0\):第 \(i + 1\) 位和 第 \(i\) 位均为 \(0\)。
一个 \(1\) 一个 \(0\):第 \(i\) 位为 \(1\),第 \(i + 1\) 位为 \(0\)。
那么,我们就可以根据上面那个式子,求一次奇数位全部变成 \(0\) 的两个数的和,把偶数位的 \(1\) 的出现次数情况求出来,求一次偶数位全部变成 \(0\) 的两个数的和,把奇数位的 \(1\) 的出现次数情况求出来。
然后,根据下面的规则逐位求解:
如果 \(m\) 第 \(i\) 位为 \(1\),那么这一位对答案的贡献就是 \(1 \ll (i + 1)\)。
如果 \(m\) 第 \(i\) 位为 \(0\),那么这一位对答案的贡献就看 \(1\) 的出现次数,如果出现次数为 \(2\),那就是 \(1 \ll (i + 1)\),如果出现次数为 \(1\),那就是 \(1 \ll i\)。
AC CODE
[code]#include #define inf 2e18#define int long longconst int N = 2e5 + 9;int ask(int x) { std::cout op; return op;}void solve(){ std::vector a(30); int tmp = 0; for(int i = 0;i < 30;i += 2) { tmp |= (1ll
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
搜娲瘠
2025-6-8 22:23:20
关注
0
粉丝关注
12
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9986
背竽
9992
猷咎
9990
4
凶契帽
9990
5
里豳朝
9990
6
处匈跑
9990
7
黎瑞芝
9990
8
恐肩
9988
9
终秀敏
9988
10
杭环
9988
查看更多