簡單版本的結論還是很容易猜到的。
首先很容易想到的第一步就是儘可能地不覆蓋地取儘可能多地區間,最後剩下了一小塊。
然後在接着原來的指針一個一個地往右問,直到不能問了爲止。
爲什麼這樣是正確的呢?首先,在這樣一步一步地往右查詢的過程中,我們會發現總是前$k-1個數加上後面的一個數。
然後題面中把EVEN加粗了,因爲你會發現,如果這樣操作,前 \(k-1\)個數在實際上只會出現奇數次
這樣把問到的一堆東西異或起來就是答案了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
using namespace std;
int t;
int n,k;
long long ans;
int ask(int f){
cout<<"? "<<f<<endl;
int x;
cin>>x;
return x;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
int f;
ans=0;
for(f=1;f+2*k-1<=n;f+=k){
ans^=ask(f);
}
for(;f+k-1<=n;++f){
ans^=ask(f);
}
cout<<"! "<<ans<<endl;
}
return 0;
}