【位运算】Strange Test—CF1632C

8 篇文章 0 订阅
7 篇文章 0 订阅

Strange Test—CF1632C

  • 本题考查了思维、位运算、数学化简能力。

思路

下面大部分是cf官方题解的原话,因为我认为cf这个题的题解写得确实很好。

取或操作最多只能用一次,因为 a   ∣   b ≥ b a~|~b \ge b a  bb,所以在使用取或操作之后,我们只能使用第二个操作(自增 b b b)。

如果我们不使用取或操作,答案就是 b − a b - a ba

如果我们使用了取或操作。在此之前,我们使用了第一个和第二个操作若干次,令结果值 a a a b b b 分别为 a ′ a' a b ′ b' b a ≤ a ′ a \leq a' aa b ≤ b ′ b \leq b' bb)。在这种情况下,答案将是 ( a ′ − a ) + ( b ′ − b ) + ( ( a ′   ∣   b ′ ) − b ′ ) + 1 = a ′ + ( a ′   ∣   b ′ ) + ( 1 − a − b ) (a' - a) + (b' - b) + ((a' \ | \ b') - b') + 1 = a' + (a' \ | \ b') + (1 - a - b) (aa)+(bb)+((a  b)b)+1=a+(a  b)+(1ab)。由于 ( 1 − a − b ) (1 - a - b) (1ab) 是常数,这等价于使 a ′ + ( a ′   ∣   b ′ ) a' + (a' \ | \ b') a+(a  b) 最小。
为了实现这个目标,我们可以递增地枚举 a ′ a' a a a a b b b 的值。对于每一个 a ′ a' a,我们需要使 a ′   ∣   b ′ a' \ | \ b' a  b 最小,而最佳的 b ′ b' b (首先满足 b ′   ≥   b b'~\ge~b b  b,其次满足 a ′ + ( a ′   ∣   b ′ ) a' + (a' \ | \ b') a+(a  b) 最小)可以按照以下方式构造:

b ′ b' b 设为零,并从高到低迭代位数。有四种情况:

  • 如果当前位的 a ′ a' a 是 0,且 b b b 是 1,则将 b ′ b' b 的当前位设为 1。
  • 如果当前位的 a ′ a' a 是 0,且 b b b 是 0,则将 b ′ b' b 的当前位设为 0。
  • 如果当前位的 a ′ a' a 是 1,且 b b b 是 1,则将 b ′ b' b 的当前位设为 1。
  • 如果当前位的 a ′ a' a 是 1,且 b b b 是 0,则将 b ′ b' b 的当前位设为 1,并停止。

这种构造 b ′ b' b 的方法并不好理解。需要想很长时间。我一开始本以为我已经理解了,但当我写这篇博客的时候发现我的理解其实是错误的,直到我写到这里才真正地理解。

C o d e Code Code

#include <bits/stdc++.h>
#define int long long
#define sz(a) ((int)a.size())
#define all(a) a.begin(), a.end()
using namespace std;
using PII = pair<int, int>;
using i128 = __int128;
const int N = 2e5 + 10;

int a, b;

void solve() {
	cin >> a >> b;
	
	int res = b - a;
	for (int a_ = a; a_ <= b - 1; a_ ++) {
		int now_res = 1 - a - b + a_;
		int b_ = b;
		for (int i = 30; i >= 0; i --) {
			if ((a_ >> i & 1) && !(b >> i & 1)) {
				b_ = ((b >> i) + 1) << i;
				break;
			}
		}
		now_res += a_ | b_;
		res = min(res, now_res);
	}
	
	cout << "       ";
	cout << res << "\n";
}

signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T = 1;
	cin >> T; cin.get();
	while (T --) solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值