首先判断大小关系,记为 f f f。
然后从最高位开始判断: u = a s k ( a ⊕ 2 i , b ) , v = a k s ( a , b ⊕ 2 i ) u=ask(a\oplus 2^i,b),v=aks(a,b\oplus 2^i) u=ask(a⊕2i,b),v=aks(a,b⊕2i)
如果此时返回的结果相同,说明一个是1,一个是0,然后根据 f f f来判断,并更新 f f f,因为每次我们都是依据当前 f f f判断。
如果此时 u = − 1 u=-1 u=−1,说明此时两个数的最高位都为1。
否则两个数的最高位都为0。
时间复杂度: O ( l o g n ) O(logn) O(logn)
// Problem: D. Ehab and another another xor problem
// Contest: Codeforces - Codeforces Round #525 (Div. 2)
// URL: https://codeforces.ml/problemset/problem/1088/D
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// Date: 2021-07-27 14:45:44
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a[n]);
}
int ask(int a,int b){
cout<<"? "<<a<<" "<<b<<'\n';
fflush(stdout);
int ans;
scanf("%d",&ans);
return ans;
}
int main(){
int a=0,b=0,f=ask(a,b);
for(int i=29;~i;i--){
int u=ask(a^(1<<i),b),v=ask(a,b^(1<<i));
if(u==v){
if(f==1) a^=(1<<i);
else b^=(1<<i);
f=u;
}
else if(u==-1){
a^=(1<<i);
b^=(1<<i);
}
}
cout<<"! "<<a<<" "<<b<<'\n';
fflush(stdout);
return 0;
}