【CF1020D】The hat(交互,二分)
题意:有n个人围成一个圈,n为偶数,每个人有一个数字a[i],保证相邻两个人的数字差为1
最多可以询问60次,要求获得一个i使得a[i]=a[i+n/2]
n<=1e5,abs(a[i])<=1e9
思路:首先n不为4的倍数时奇偶性不同,无解
将+1和-1设为b[i],所求即为两段长度为n并且和为0的数列
设f(i)=a[i+n/2]-a[i]
二分答案,设当前区间为[l,r],中点为mid
若f(l)与f(mid)异号,答案若存在则(l,mid)中必定有解
若f(r)与f(mid)异号,答案若存在则(mid+1,r)中必定有解
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 #include<bitset> 12 using namespace std; 13 typedef long long ll; 14 typedef unsigned int uint; 15 typedef unsigned long long ull; 16 typedef pair<int,int> PII; 17 typedef vector<int> VI; 18 #define fi first 19 #define se second 20 #define MP make_pair 21 #define N 210000 22 #define M 51 23 #define MOD 1000000007 24 #define eps 1e-8 25 #define pi acos(-1) 26 #define oo 3e14 27 28 int a[N],b[N],n; 29 30 int query(int x) 31 { 32 if(b[x]) return a[x]; 33 b[x]=1; 34 printf("? %d\n",x); 35 fflush(stdout); 36 int l,r; 37 scanf("%d",&l); 38 printf("? %d\n",x+n/2); 39 fflush(stdout); 40 scanf("%d",&r); 41 if(l==r) 42 { 43 printf("! %d\n",x); 44 exit(0); 45 } 46 a[x]=r-l; 47 } 48 49 void solve(int l,int r) 50 { 51 int mid=(l+r)>>1; 52 int sl=query(l); 53 int sr=query(r); 54 int sm=query(mid); 55 if((ll)sl*sm<0) solve(l,mid); 56 else if((ll)sr*sm<0) solve(mid+1,r); 57 } 58 59 int main() 60 { 61 scanf("%d",&n); 62 if(n%4) printf("! -1\n"); 63 else 64 { 65 solve(1,n/2); 66 printf("! -1\n"); 67 } 68 return 0; 69 }
null