E. Vlad and a Pair of Numbers
题目有公式 a⊕b=(a+b)/2=xa ⊕ b = (a + b) / 2 = xa⊕b=(a+b)/2=x, 给你的是 xxx,让输出一组满足题目要求的 a,ba,ba,b,没有就输出−1-1−1。
首先分析异或的性质,不同为1,相同为0。所以可以把 xxx 给二进制化得到字符串s,在s是1的位置上aaa 和 bbb 肯定一个是0,一个是1。不妨假定把所有的1都给 aaa ,然后去分析 (a+b)/2(a + b) / 2(a+b)/2,这就相当于把 a+ba + ba+b 右移一位,所以只要让 aaa 和 bbb 在 s 为1的位置的上一个地方变成1就可以了,如果下一个位置的地方也是1的话就无解,输出-1。证明如下:
我们不妨通过 xxx 来反推 a+ba + ba+b,可以得到一个 1 的位置永远都比 xxx 的 1 的位置要往前一位,所以要得到这个二进制数只要在的1的后一位的地方变成1就好了,这里要是不懂得话就找一个数推一下,下面是一个例子。
10进制 | 二进制 |
---|---|
x | 001010100 |
a | 001111110 |
b | 000101010 |
a + b | 010101000 |
#include using namespace std;#define int long long
typedef long long LL;
const int N = 5e5 + 10, mod = 998244353;void solve()
{int n;cin >> n;int a = 0, b = 0;if (n & 1) cout << -1 << '\n';else {for (int i = 1; i <= 30; i ++ ){if (n >> i & 1) {if (n >> (i - 1) & 1){cout << -1 << '\n';return;}}}for (int i = 1; i <= 30; i ++ ){if (n >> i & 1) {a += 1 << i;a += 1 << (i - 1);b += 1 << (i - 1);}}cout << a << ' ' << b << '\n'; }
}signed main()
{int T = 1;cin >> T;while (T -- ){solve();}return 0;
}
下一篇:用Qt画一个仪表盘