題目連接:https://www.luogu.org/problemnew/show/P1309ios
題解:c++
每次比賽前,每一個人都是按照分數降序排好的,那麼比賽完後,將選手按輸贏分紅兩組,順序依然按照原順序,那麼顯然組內的分數依然是降序的。只要將兩個組從新 $O(n)$ 合併便可。spa
這種合併相似於歸併排序裏的merge操做。code
AC代碼:blog
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e5+5; int n,r,q; struct P{ int id; ll w,s; bool operator>(const P& oth)const { if(s==oth.s) return id<oth.id; return s>oth.s; } }p[maxn],win[maxn],los[maxn]; int wsz,lsz; void print() { for(int i=1;i<=2*n;i++) printf("%d: %I64d %I64d\n",p[i].id,p[i].s,p[i].w); cout<<endl; } int main() { ios::sync_with_stdio(0); cin>>n>>r>>q; for(int i=1;i<=2*n;i++) p[i].id=i; for(int i=1;i<=2*n;i++) cin>>p[i].s; for(int i=1;i<=2*n;i++) cin>>p[i].w; sort(p+1,p+2*n+1,greater<P>{}); while(r--) { wsz=lsz=0; for(int i=1;i<=2*n;i+=2) { if(p[i].w>p[i+1].w) { p[i].s++; win[wsz++]=p[i]; los[lsz++]=p[i+1]; } else { p[i+1].s++; win[wsz++]=p[i+1]; los[lsz++]=p[i]; } } int i=0,j=0,k=1; while(i<wsz && j<=lsz) { if(win[i]>los[j]) p[k++]=win[i++]; else p[k++]=los[j++]; } while(i<wsz) p[k++]=win[i++]; while(j<lsz) p[k++]=los[j++]; } cout<<p[q].id<<endl; }