首先中间那段没啥用,只考虑左右两端就行
那么我们在l,l+1和r−1,r中取不为0的值,即为斜率k
二分时,如果fmid−fl=k∗(mid−l),说明a∈[mid,r),否则a∈[l,mid)
注意:这题存在卡二分次数的问题,所以如果找斜率的时候出现了k和0,直接输出并结束,不然会超次数然后WA;另外找斜率时不要用取max,不然次数也会炸。
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll T,l,r;
inline ll query(ll l,ll r){
printf("? %lld %lld\n",l,r); fflush(stdout);
ll val; scanf("%lld",&val);
return val/(r-l);
}
inline void answer(ll k,ll b){
printf("! %lld %lld\n",k,b); fflush(stdout);
}
int main(){
scanf("%lld",&T);
while(T--){
scanf("%lld %lld",&l,&r);
ll k=query(l,l+1);
if(k==0) k=query(r-1,r);
else while(r-l>1){
ll mid=(l+r)>>1;
if(query(l,mid)==k) l=mid;
else r=mid;
}
answer(k,l);
}
return 0;
}