考虑倍增,现在已经知道答案 \(ans \bmod 2^k\) 的值,考虑求出 \(ans \bmod 2^{k+1}\) 的值。
设 \(x = ans \bmod 2^k\),则 \(ans \bmod 2^{k+1} = x\) 或 \(ans \bmod 2^{k+1} = x + 2^k\)。两个都试一遍,如果 \(d(ans - x) \bmod (k+1) = 0\) 就可以认为他是 \(2^k\) 的倍数,如果有多个数满足条件就都保留下来,最后得到 \(ans \bmod 2^{64}\),就是答案(显然这样的数只会有一个)。
实际上状态数不会太多,询问可以记忆化,次数在 \(500\) 左右。
两个数先试哪个可以随一下,这样可能可以减少常数。
std::mt19937 mtrd(time(0));
int solve(ll x,int dep){if((1ll<<dep)>n){ans=(1ll<<dep)-x;return 1;}ll k=(1ll<<dep);int op=mtrd()%2;for(int t:{0^op,1^op}){if(Query(x+k*t)%(dep+1)==0)if(solve(x+k*(t^1),dep+1))return 1;}return 0;
}