码迷,mamicode.com
首页 > 其他好文 > 详细

题解 SP18939 【KSMALL - K-th smallest number】

时间:2020-12-08 12:34:42      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:--   大于   number   its   方式   ber   提交   sp1   双指针   

发现提交记录全用的是nth_element...(真就STL依赖症?)

提供一种 \(\mathcal O(n)\) 的分治算法。

Solution

我们可以用类似快排的方式。在快排的分治中,若双指针(\(i,j\))已经扫描完这段区间 \([l,r]\),即 \(i\) 已经大于 \(j\),就会把它分为三部分:\([l,j],(j,i),[i,r]\)。然后判断 \(k\) 的位置,如果在 \([l,j]或[i,r]\),就继续分治,否则答案就是 \((j,i)\) 的第一个数 \(array_{j+1}\)

Code

#include<bits/stdc++.h>
using namespace std;
unsigned d[5000005];
void randomize(unsigned a,unsigned b,unsigned mod)
{
    for( int i=0 ; i<5000000 ; i++ )
    {
        a = 31014 * (a & 65535) + (a >> 16);
        b = 17508 * (b & 65535) + (b >> 16);
        d[i] = ((a << 16) + b) % mod;
    }
}
int k;
unsigned find(int l,int r) {
    unsigned x=d[(l+r)/2];
    int i=l,j=r;
    do{//类快排部分
        while(d[i]<x)i++;
        while(d[j]>x)j--;
        if(i<=j)swap(d[i],d[j]),i++,j--;
    }while(i<=j);//双指针扫描
    if(k<=j)return find(l,j);
    else if(i<=k)return find(i,r);
    else return d[j+1];
}
int main(){
    unsigned a,b,mod;
    scanf("%u%u%u%d",&a,&b,&mod,&k);
    randomize(a,b,mod);k--;
    printf("%u\n",find(0,4999999));
    return 0;
}

题解 SP18939 【KSMALL - K-th smallest number】

标签:--   大于   number   its   方式   ber   提交   sp1   双指针   

原文地址:https://www.cnblogs.com/aday526/p/solution-sp18939.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!