标签:-- 大于 number its 方式 ber 提交 sp1 双指针
发现提交记录全用的是nth_element...(真就STL依赖症?)
提供一种 \(\mathcal O(n)\) 的分治算法。
我们可以用类似快排的方式。在快排的分治中,若双指针(\(i,j\))已经扫描完这段区间 \([l,r]\),即 \(i\) 已经大于 \(j\),就会把它分为三部分:\([l,j],(j,i),[i,r]\)。然后判断 \(k\) 的位置,如果在 \([l,j]或[i,r]\),就继续分治,否则答案就是 \((j,i)\) 的第一个数 \(array_{j+1}\)。
#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