E1. Salyg1n and Array (simple version)
从 n-(n%k)-k+1 问到 n-k+1,问了 n%k+1 项为奇数,所有项出现次数为奇数;
#include <bits/stdc++.h>
using namespace std;
int n,k;
int ask(int i)
{
cout<<flush<<"? "<<i<<endl;
int res;
cin>>res;
return res;
}
void solve()
{
cin>>n>>k;
int ans=0;
if(n%k==0){
for(int i=1;i<=n;i+=k)ans^=ask(i);
cout<<flush<<"! "<<ans<<endl;
}else{
for(int i=1;i<=n-(n%k)-k;i+=k)ans^=ask(i);
for(int i=n-(n%k)-k+1;i<=n-k+1;i++)ans^=ask(i);
cout<<flush<<"! "<<ans<<endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int _t;cin>>_t;
while(_t--){
solve();
}
return 0;
}
E2. Salyg1n and Array (hard version)
不能全问,50+50 过大;问一次问不完,问两次重复项出现偶数会被约掉,问三次最优;
由于 n%k 为偶数,故三次起始位置分别为 n-(n%k)-k+1、n-(n%k)/2-k+1、n-k+1;
每次向后 (n%k)/2 个单位;共三段;
#include <bits/stdc++.h>
using namespace std;
int n,k;
int ask(int i)
{
cout<<flush<<"? "<<i<<endl;
int res;
cin>>res;
return res;
}
void solve()
{
cin>>n>>k;
int ans=0;
if(n%k==0){
for(int i=1;i<=n;i+=k)ans^=ask(i);
cout<<flush<<"! "<<ans<<endl;
}else{
for(int i=1;i<=n-(n%k)-k;i+=k)ans^=ask(i);
ans^=ask(n-(n%k)-k+1);
ans^=ask(n-(n%k)-k+1+(n%k)/2);
ans^=ask(n-k+1);
cout<<flush<<"! "<<ans<<endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int _t;cin>>_t;
while(_t--){
solve();
}
return 0;
}