2017多校第二场 HDU 6040 Hints of sd0061 快速排序

来源:互联网 发布:世界顶级音乐学院知乎 编辑:程序博客网 时间:2024/06/01 21:05

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6040

题意:通过题目所给函数求出a数组,然后根据b数组排a数组。ai必须是a数组中第(bi+1)大的数。

解法:先通过下标对b数组排序。然后扫一遍b数组,如果相邻两个位置b相同,那么就还选上一个a(因为n可以小于m),所以可以多选。然后就可以利用快拍的思想来优化。因为是bi+1个数,所以可以把比a[bi+1]小的数放到左边,大的放在右边,这样下次扫b的时候只需要扫一边,这样优化就能过题了。

#include <bits/stdc++.h>using namespace std;const int maxn = 1e7+7;pair <unsigned, unsigned> p[102];unsigned a[maxn];int b[102], ans[102];unsigned x, y, z;unsigned rng61() {  unsigned t;  x ^= x << 16;  x ^= x >> 5;  x ^= x << 1;  t = x;  x = y;  y = z;  z = t ^ x ^ y;  return z;}void qsort(int l, int r, int L, int R){    if(l > r || L > R) return;    if(l == r){        for(int i=L; i<=R; i++){            p[i].first = a[l];        }        return;    }    int i = l, j = r, val = a[(i+j)/2];    do{        while(a[i]<val) i++;        while(a[j]>val) j--;        if(i <= j){            swap(a[i], a[j]);            i++;            j--;        }    }while(i<=j);    int pos1 = upper_bound(b+L, b+R+1, j) - b;    qsort(l, j, L, pos1-1);    if(j + 2 == i){        int mid = j + 1;        int pos2 = upper_bound(b + L, b + R + 1, mid) - b;        for(int x = pos1; x < pos2; x++){            p[x].first = a[mid];        }        pos1 = pos2;    }    qsort(i, r, pos1, R);}int main(){    int n, m, ks = 0;    while(~scanf("%d %d %u %u %u", &n,&m,&x,&y,&z))    {        for(int i=1; i<=n; i++){            a[i] = rng61();        }        for(int i=1; i<=m; i++){            scanf("%u", &p[i].first);            p[i].first++;            p[i].second = i;        }        sort(p+1, p+m+1);        for(int i=1; i<=m; i++){            b[i] = p[i].first;        }        qsort(1, n, 1, m);        for(int i=1; i<=m; i++){            ans[p[i].second] = p[i].first;        }        printf("Case #%d:", ++ks);        for(int i=1; i<=m; i++){            printf(" %u", ans[i]);        }        printf("\n");    }    return 0;}
原创粉丝点击