卡了很久了,一直是随机错点,每个点都有一定概率对

P1923 【深基9.例4】求第 k 小的数

Emerald_26 @ 2023-09-23 09:29:54

求助,代码看了半天了不知道哪有问题,既然点随机错我猜大概和随机数的选取有关,虽然我也不确定。。。

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N = 5e6 + 10;
int a[N], b[N];

int randint(int l, int r){ // 生成在 [l, r] 之间的随机数
    int tmp = rand();
    if(tmp < 0) tmp = -tmp;
    return tmp % (r - l + 1) + l;
}

int find(int l, int r, int k) {
    //if(k < l || k > r) return -114514;
    if(l >= r) return a[l];
    int pos = randint(l, r);
    int pl = l, pr = r;
    for(int i = l; i <= r; i++) {
        if(a[i] < a[pos]) b[pl++] = a[i];
        else if(a[i] > a[pos]) b[pr--] = a[i];
    }
    for(int i = pl; i <= pr; i++) b[i] = a[pos];
    for(int i = l; i <= r; i++) a[i] = b[i];
    //printf("%d   %d %d\n", pos, pl, pr);
    if(pl <= k && k <= pr) return a[pos];
    if(k < pl) return find(l, pl - 1, k);
    if(k > pr) return find(pr + 1, r, k);
    return -114514;
    // 0~(pl-l-1)  (pl-l)~(pr-l)  (pr-l+1)~(r-l)
}

int main() {
    //freopen("test.in", "r", stdin);
    //freopen("test.out", "w", stdout);
    int n, k;
    srand(time(NULL));
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    printf("%d\n", find(1, n, k + 1));
    return 0;
}

|