1. 程式人生 > 其它 >Codeforces Round #781 D. GCD Guess

Codeforces Round #781 D. GCD Guess

傳送門

題目大意

互動題,每次詢問給出 \(a,b\) , 得到 \(gcd(x+a,x+b)(1\leq x\leq10^9,1\leq a,b\leq2\times10^9)\)\(30\) 次詢問內求出 \(x\)

思路

考慮通過回答來確定 \(x\) 二進位制上每一位的值,我們每次可以記錄 \(0\)\(i\) 位的答案為 \(ans_i\) ,查詢 \(gcd(x-ans_i+2^{i+1},x - ans_i +2^{i+1}+2^{i+2})=gcd(x-ans_i+2^{i+1},2^{i+2})\) 來確定第 \(i+1\) 位的值,如果得到的回答 \(\neq 2^{i+2}\)

,那麼第 \(i+1\) 位就為 \(1\) ,否則為 \(0\)

程式碼

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
using PII = pair<int, int>;
using TP = tuple<int, int, int>;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2
//#define rc p*2+1
//#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
//#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 200010;

LL T, A[35];

void solve()
{
	LL res, ans = 0;
	for (int i = 0; i < 30; i++)
	{
		LL a = A[i] - ans, b = A[i] + A[i + 1] - ans;
		cout << "? " << a << ' ' << b << endl;
		cin >> res;
		if (res == A[i + 1])
			ans ^= (1LL << i);
	}
	cout << "! " << ans << endl;
}

int main()
{
	IOS;
	LL num = 1;
	for (int i = 0; i <= 30; i++)
		A[i] = num, num *= 2;
	cin >> T;
	while (T--)
		solve();

	return 0;
}