遠回りしすぎたけど反省のため書いておく。
https://atcoder.jp/contests/abc169/tasks/abc169_e
問題
N要素の整数列がある。i番目の値は[A[i],B[i]]の範囲を取るとする。
中央値としてあり得るのは何通りか。
解法
中央値の最小値をX、最大値をYとすると、Nが奇数なら[X,Y]の範囲を1ごとに、偶数なら1/2ごとの値が取れる。
あとはX,Yを求めればよい。
自分は無駄に二分探索で頑張ったのだがAの中央値がX、Bの中央値がYになるのだそうで。
以下無駄に二分探索してしまったコード。
int N; int L[202020],R[202020]; int S[2][402020]; int ok1(int v,int tar) { int C[3]={}; int i; FOR(i,N) { if(R[i]<v) C[0]++; else if(v<L[i]) C[2]++; else C[1]++; } return C[0]<tar; } int ok2(int v,int tar) { int C[3]={}; int i; FOR(i,N) { if(R[i]<v) C[0]++; else if(v<L[i]) C[2]++; else C[1]++; } return C[2]<tar; } void solve() { int i,j,k,l,r,x,y; string s; cin>>N; vector<int> V; FOR(i,N) { cin>>L[i]>>R[i]; V.push_back(L[i]); V.push_back(R[i]+1); } int ma[2]={}; int mi[2]={1<<30,1<<30}; FOR(i,2) { int tar; if(N%2==0) { tar=N/2+i; } else { tar=(N+1)/2; } for(j=29;j>=0;j--) { if(ok1(ma[i]+(1<<j),tar)) ma[i]+=1<<j; if(ok2(mi[i]-(1<<j),tar)) mi[i]-=1<<j; } } //cout<<mi[0]<<" "<<mi[1]<<" "<<ma[0]<<" "<<ma[1]<<endl; if(N%2==0) { cout<<(ma[1]+ma[0]-mi[0]-mi[1])+1<<endl; } else { cout<<ma[0]-mi[0]+1<<endl; } }
まとめ
上位がかなり短時間で解いてるし、これはおかしいかもとは思ったんだけど、500ptだしやりかねないかな…と。