题目描述#
给定两个整型数组
输入格式#
第一行三个整数,分别表示
输出格式#
一个整数表示第
样例#
4 6 8
1 3 6 7
0 2 4 5 9 11plaintext7plaintext提示#
Sol.1 双指针扫描#
时间复杂度
不赘述
Sol.2 中位数BFPRT#
时间复杂度
BFPRT 求有序数组中位数#
可以通过递归求解计算,时间复杂度
比如,我们有如下长度为

我们取每个数组中位数进行比较

若

那么我们只需要在蓝色区间内查找中位数

此时我们有如下长度为

若

但是当我们去掉不可能的部分后,剩下的部分长度不等

此时我们可以把

若
若

直到最后每个数组只剩

在本例中,中位数为
若上述某一步奇偶性或大小表示不同,那么相反操作即可
int dfs(int sa,int ea,int sb,int eb){
if(sa==ea)return min(a[sa],b[sb]);//终止条件
int ma=(sa+ea)>>1,mb=(sb+eb)>>1; //数组a,b的中间位置
bool ji=(ea-sa+1)&1; //判断奇偶
if(a[ma]>b[mb]){
if(ji){
if(b[mb]>=a[ma-1]) return b[mb];
else return dfs(sa,ma-1,mb+1,eb);
}else return dfs(sa,ma,mb+1,eb);
}else{
if(ji){
if(a[ma]>=b[mb-1]) return a[ma];
else return dfs(ma+1,ea,sb,mb-1);
}else return dfs(ma+1,ea,sb,mb);
}
}cpp利用BFPRT求第K小值#
如给定如下有序数组

长度分别为
对于给定的
对于第一种,若

即
int solve1(){
return dfs(1,k,1,k);
}cpp对于第二种,若
因为在本例中

若
若

即
int solve2(){
if(n<m){
if(b[k-n]>=a[n]) return b[k-n];
else return dfs(1,n,k+1-n,k);
}else{
if(a[k-m]>=b[m]) return a[k-m];
else return dfs(k+1-m,k,1,m);
}
}cpp对于第三种,若
我们需要对

若
若
若

即
int solve3(){
if(a[k-m]>=b[m]) return a[k-m];
else if(b[k-n]>=a[n]) return b[k-n];
else return dfs(k+1-m,n,k+1-n,m);
}cpp总体时间复杂度全部在BFPRT求中位数上,复杂度为
Code#
#include<iostream>
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)<(y)?(y):(x))
using namespace std;
inline long long read(){
long long x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
return x*f;
}
long long n,m,k,a[10000005],b[10000005];
long long dfs(long long sa,long long ea,long long sb,long long eb){
if(sa==ea)return min(a[sa],b[sb]);
long long ma=(sa+ea)>>1,mb=(sb+eb)>>1;
bool ji=(ea-sa+1)&1;
if(a[ma]>b[mb]){
if(ji){
if(b[mb]>=a[ma-1]){
return b[mb];
}else{
return dfs(sa,ma-1,mb+1,eb);
}
}else{
return dfs(sa,ma,mb+1,eb);
}
}else{
if(ji){
if(a[ma]>=b[mb-1]){
return a[ma];
}else{
return dfs(ma+1,ea,sb,mb-1);
}
}else{
return dfs(ma+1,ea,sb,mb);
}
}
}
void solve1(){
cout<<dfs(1,k,1,k);
}
void solve2(){
if(n<m){
if(b[k-n]>=a[n]) cout<<b[k-n];
else cout<<dfs(1,n,k+1-n,k);
}else{
if(a[k-m]>=b[m]) cout<<a[k-m];
else cout<<dfs(k+1-m,k,1,m);
}
}
void solve3(){
if(a[k-m]>=b[m]) cout<<a[k-m];
else if(b[k-n]>=a[n]) cout<<b[k-n];
else cout<<dfs(k+1-m,n,k+1-n,m);
}
int main(){
n=read(),m=read(),k=read();
for(long long i = 1;i<=n;i++) a[i]=read();
for(long long i = 1;i<=m;i++) b[i]=read();
long long minn=min(n,m),maxn=max(n,m);
if(k<=minn) solve1();
else if(k>minn && k<=maxn) solve2();
else solve3();
}cpp
Comments
View on GitHub