CF1665D GCD Guess 题解

可能更好的阅读体验

Upd on 2022.6.29:更正了一处小错误。

题目大意

交互题,需要猜一个正整数 \(x\)\(x\le 10^9\)),每次询问输出给出 \(a,b\),你可以得到 \(\gcd(x+a,x+b)\) 的值,询问此处不超过 \(30\) 次。要求 \(a,b\le 2\times 10^9\)

题目解析

显然 \(\gcd(x+a,x+b)=\gcd(x+a,b-a)\)
这样我们就可以猜出 \(x\) 在二进制下的每一位。

我们从低位到高位猜,假设现在猜的是从右往左第 \(i\) 位,那么我们现在就已经知道了右边 \(i-1\) 位,这些位的数值的和记作 \(y\),令 \(a=2^{i-1}-y\)\(b=2^{i}+2^{i-1}-y\)。假设返回的数是 \(m\)。 如果 \(m=2^i\),也就是说,在第 \(i\) 位加上了 \(1\) 会产生进位,那么这一位就是 \(1\),反之这一位就是 \(0\)

代码:

int x,tmp;
void work(){
	int i; x=0; for(i=1;i<=30;i++){
		cout<<"? "<<(1<<i-1)-x<<' '<<(1<<i-1)+(1<<i)-x<<endl; fflush(stdout);
		cin>>tmp; if(tmp==(1<<i)) x|=1<<(i-1);
		//cout<<x<<endl;
	} cout<<"! "<<x<<endl; fflush(stdout); return;
}
posted @ 2022-04-10 15:45  jiangtaizhe001  阅读(160)  评论(0编辑  收藏  举报