【CF1020D】The hat(提答,二分)
阿新 • • 發佈:2018-12-05
題意:有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 }