洛谷 - P1309 - 瑞士轮 - 排序

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\n",p[q-1].id);
}

效果惊人,又学了一手好东西。

猜你喜欢

转载自www.cnblogs.com/Yinku/p/10317387.html
今日推荐