#847(Div3)E. Vlad and a Pair of Numbers

原题链接:

E. Vlad and a Pair of Numbers

题意:

题目有公式 a ⊕ b = ( a + b ) / 2 = x a ⊕ b = (a + b) / 2 = x ab=(a+b)/2=x, 给你的是 x x x,让输出一组满足题目要求的 a , b a,b ab,没有就输出 − 1 -1 1

解题:

首先分析异或的性质,不同为1,相同为0。所以可以把 x x x 给二进制化得到字符串s,在s是1的位置上 a a a b b b 肯定一个是0,一个是1。不妨假定把所有的1都给 a a a ,然后去分析 ( a + b ) / 2 (a + b) / 2 (a+b)/2,这就相当于把 a + b a + b a+b 右移一位,所以只要让 a a a b b b 在 s 为1的位置的上一个地方变成1就可以了,如果下一个位置的地方也是1的话就无解,输出-1。证明如下:
我们不妨通过 x x x 来反推 a + b a + b a+b,可以得到一个 1 的位置永远都比 x x x 的 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;
}

你可能感兴趣的:(c++,数学,二进制)