洛谷
https://www.luogu.org/problemnew/show/P1309
一开始写的直接快排没想到真的TLE了。
想到每次比赛每个人前移的量不会很多,但是不知从哪里开始优化。
搜索一下原来是用归并排序的。
每次比赛过后,成功者的顺序不变,失败者的顺序也不变。那么把两个数组合并的复杂度将会是O(n)的,降低了20倍复杂度(一个logn)。
别人还提到STL有一个merge(f1,l1,f2,l2,r,cmp()),可以把容器1和容器2的结果合并到容器r中。
试一下。
#include<bits/stdc++.h> using namespace std; #define ll long long int n,r,q; struct P{ int id; int score; int w; }p[2000005]; struct cmp{ bool operator()(P p1,P p2){ if(p1.score!=p2.score) return p1.score>p2.score; else return p1.id<p2.id; } }; /*struct cmp2{ bool operator(P p1,P p2){ return p1.w<p2.w; } };*/ P t1[1000005]; P t2[1000005]; P res[1000005]; int main(){ scanf("%d%d%d",&n,&r,&q); int tn=2*n; for(int i=0;i<tn;i++){ scanf("%d",&p[i].score); p[i].id=i+1; } for(int i=0;i<tn;i++){ scanf("%d",&p[i].w); } sort(p,p+tn,cmp()); while(r--){ for(int i=0;i<n;i++){ if(p[2*i].w<p[2*i+1].w){ p[2*i+1].score++; t1[i]=p[2*i+1]; t2[i]=p[2*i]; } else{ p[2*i].score++; t1[i]=p[2*i]; t2[i]=p[2*i+1]; } } merge(t1,t1+n,t2,t2+n,p,cmp()); /*sort(p,p+tn,cmp());*/ } printf("%d ",p[q-1].id); }
效果惊人,又学了一手好东西。