题面翻译
给定非负整数 \(a\),\(b\),\(C\),判断是否存在一对二元组 \((x,y)\) 满足以下条件:
- \(0<x<2^{60}\)
- \(0<y<2^{60}\)
- \(\operatorname{popcount}(x)=a\)
- \(\operatorname{popcount}(y)=b\)
- \(x\) 对 \(y\) 进行位异或的结果是 \(C\)
其中 \(\operatorname{popcount}\) 指一个数转化为二进制后所有位上的 \(1\) 的个数。
若存在二元组则输出这两个数,否则输出 -1
。
样例 #1
样例输入 #1
3 4 7
样例输出 #1
28 27
样例 #2
样例输入 #2
34 56 998244353
样例输出 #2
-1
样例 #3
样例输入 #3
39 47 530423800524412070
样例输出 #3
540431255696862041 10008854347644927
提示
制約
- $ 0\leq\ a\leq60 $
- $ 0\leq\ b\leq60 $
- $ 0\leq\ C\lt2\ ^\ {60} $
- 入力はすべて整数
Sample Explanation 1
$ (X,Y)=(28,27) $ は条件を満たします。 $ X,Y $ を $ 2 $ 進法で表記するとそれぞれ 11100
と 11011
になります。 - $ X $ を $ 2 $ 進法で表記すると 11100
になるので、$ \operatorname{popcount}(X)=3 $ です。 - $ Y $ を $ 2 $ 進法で表記すると 11011
になるので、$ \operatorname{popcount}(Y)=4 $ です。 - $ X\oplus\ Y $ を $ 2 $ 進法で表記すると 00111
となり、$ X\oplus\ Y=7 $ です。 条件を満たす非負整数の組が複数存在する場合どれを出力しても構わないため、例えば 42 45
と出力しても正解になります。
Sample Explanation 2
条件を満たす非負整数の組は存在しません。
Sample Explanation 3
出力すべき値が $ 32\operatorname{bit} $ 整数に収まらない場合があります。
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
int x,y,totx1,tot0,toty1;
ull c;
int cal(ull x){
int cnt = 0;
while(x){
if(x & 1) cnt++;
x >>= 1;
}
return cnt;
}
int main(){
cin>>x>>y>>c;
int cnt1 = cal(c);
if((x + y - cnt1) % 2 != 0 || x+y < cnt1 ){//
cout<<"-1"<<endl;
return 0;
}
if(abs(x-y) > cnt1 || (x + y - cnt1) / 2 > 60 - cnt1){//
cout<<"-1"<<endl;
return 0;
}
int p = (x + y - cnt1)/2;
x -= p;
y -= p;
ull xx = 0, yy = 0;
for(int i = 0; i < 63; i++){//111
if(((c >> i) & 1) == 1){
if(totx1 < x){
xx |= (1ull<<i);
yy |= (0ull<<i);
totx1++;
}
else if(toty1 < y){
yy |= (1ull<<i);
xx |= (0ull<<i);
toty1++;
}
}
else{
if(tot0 < p){
xx |= (1ull<<i);
yy |= (1ull<<i);
tot0++;
}
else{
xx |= (0ull<<i);
yy |= (0ull<<i);
}
}
}
cout<<xx<<" "<<yy<<endl;
return 0;
}