穿越火线 1775 C

题面大意

有一个数 $ n $ ,找一个最小的 $ m \ (m \geq n) $,使得 $ \text{&} _ {k = n} ^ {m} k = x $ 。

题面关键

“不保留的位”下面的位(包括这一位)清空,再加上一个数让它变大一点,这就是下限(所有的结果中最小的)。
“保留的位”相同,但是是上限。

解题思路

那么如何求出这个数呢?

  1. (n >> (j + 1)):那些位置都剔除掉,原数也除以一大截。
  2. ((n >> (j + 1)) + 1):加上一个数。
  3. ((n >> (j + 1)) + 1) << (j + 1):把 0 加回来。

思路要点

AC 代码

// Problem: C. Interesting Sequence
// Contest: Codeforces - Codeforces Round #843 (Div. 2)
// URL: https://codeforces.com/contest/1775/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		long long n, m;
		cin >> n >> m;
		if ((n & m) != m) {
			puts("-1");
			continue;
		}
		long long mn = n, mx = 5e18;
		for (int j = 0; j < 62; j++) {
			if ((n ^ m) & (1ll << j)) {
				mn = max(mn, ((n >> (j + 1)) + 1) << (j + 1));
			} else if ((n | m) & (1ll << j)) {
				mx = min(mx, ((n >> (j + 1)) + 1) << (j + 1));
			}
		}
		if (mn < mx) {
			printf("%lld\n", mn);
		} else {
			puts("-1");
		}
	}
	return 0;
}
posted @ 2023-01-11 11:15  A-Problem-Solver  阅读(29)  评论(0编辑  收藏  举报