//不要着急,耐心一点,相信自己,不要摆烂,一定要坚持
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+10;
int a[N],b[N];
map<int,int>mp;
bool judge(int l,int r) {
int ans1=0,ans2=0;
int mid=(l+r)/2;
cout<<"? "<<l<<" "<<mid<<endl;
mp.clear();
for(int i=l;i<=mid;i++)mp[i]=1;
for(int i=l;i<=mid;i++){
cin>>a[i];
}
for(int i=l; i<=mid; i++) {
if(mp[a[i]]==1)ans1++;
}
if(ans1%2==1)return true;
else return false;
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);
cout.flush();
int t;
cin>>t;
while(t--) {
int n;
cin>>n;
int l=1,r=n;
cout<<"? "<<l<<" "<<r<<endl;
for(int i=l;i<=r;i++)cin>>b[i];
while(l<=r) {
int mid=(l+r)/2;
if(judge(l,r)==1)r=mid-1;
else l=mid+1;
}
cout<<"! "<<b[l]<<endl;
}
return 0;
}
题意:我给对方一组数,对方将两个数对换若干次,但每个数只能操作一次,直到只有一个数不动,我每次询问对方第l到第r之间是哪些数,最多询问十五次,判断哪个数没动(经分析知在原序列里恰好在自己应有位置上的数就是答案)
分析:因此我们可以把每个位置上的数都询问一遍,但是由于n为1e4,但题目只允许询问15次,因此采用二分(2^15>10000),每次询问选一半,判断答案是否在这一半里,不是就在另一半,然后分另一半,判断函数原理:如果这半数里本来就应在这部分里的个数为偶数,说明很有可能对换是成对成对交换,因此答案肯定不在这一半里,因此个数是奇数说明答案在里面,所以判断符合在原本区间的个数的奇偶性就可