1. 程式人生 > >【CF1020D】The hat(提答,二分)

【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 }