Codevs_P3299 有序数组合并求第K大问题(Treap)
来源:互联网 发布:linux boot分区 编辑:程序博客网 时间:2024/06/05 09:03
传送门
九章算法面试题
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
给出两个有序数组A和B(从小到大有序),合并两个有序数组后新数组c也有序,询问c数组中第k大的数
假设不计入输入输出复杂度,你能否给出一个O(logN)的方法?
输入描述 Input Description
第一行输入三个整数n、m和k
第二行输入n个用空格隔开的整数表示数组A
第三行输入m个用空格隔开的整数表示数组B
输入保证A和B数组非递减
输出描述 Output Description
合并两个数组之后的第k大的数
样例输入 Sample Input
2 3 4
1 2
1 1 5
样例输出 Sample Output
2
数据范围及提示 Data Size & Hint
1<=n,m<=1000000
1<=k <=n+m
#include<cstdio>#include<cstdlib>#include<set>#include<iostream>using namespace std;struct Node{ Node *ch[2];//左右子树 int r,v,s; //随机优先值,值,节点总数 Node(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1;} bool operator < (const Node &a) const{return r<a.r;} int comp(int x) const{if(x==v) return -1;return x<v?0:1;} void maintain(){s=1;if(ch[0]!=NULL) s+=ch[0]->s;if(ch[1]!=NULL) s+=ch[1]->s;}}*root;void rotate(Node* &o,int d){//旋转 d=0左旋 d=1右旋 Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; o->maintain();k->maintain();o=k;}void insert(Node* &o,int x){//插入x if(o==NULL) o=new Node(x); else{ int d=(x<o->v?0:1); insert(o->ch[d],x); if(o->ch[d]->r > o->r) rotate(o,d^1); } o->maintain();}void remove(Node* &o,int x){//删除节点 int d=o->comp(x); if(d==-1){ Node* u=o; if(o->ch[0]!=NULL&&o->ch[1]!=NULL){ int d2=(o->ch[0]->r > o->ch[1]->r?1:0); rotate(o,d2);remove(o->ch[d2],x); }else{ if(o->ch[0]==NULL) o=o->ch[1];else o=o->ch[0]; delete u; } }else remove(o->ch[d],x); if(o!=NULL) o->maintain();}int kth(Node* o,int k){//第k小 if(o==NULL||k<=0||k>o->s) return 0; int s=(o->ch[0]==NULL?0:o->ch[0]->s); if(k==s+1) return o->v; else if(k<=s) return kth(o->ch[0],k); else return kth(o->ch[1],k-s-1); }#define N 30005 int n,m,k,x;int main(){ scanf("%d%d%d",&n,&m,&k);root=NULL; for(int i=1;i<=n;i++) {scanf("%d",&x);insert(root,x);} for(int i=1;i<=m;i++) {scanf("%d",&x);insert(root,x);} printf("%d",kth(root,k)); return 0;}
0 0
- Codevs_P3299 有序数组合并求第K大问题(Treap)
- wikioi 3299 有序数组合并求第K大问题
- 关于求数组中的第k大问题
- 两个有序数组,求有序合并以后的第K个元素
- 两个有序数组,求第K小数
- 复杂度为log(m+n)下求有序数组A和B有序合并之后第k小的数
- 两个有序数组合并找第k个元素
- 合并k个有序数组
- 合并K个有序数组
- 合并K个有序数组
- 如何求两个有序数组的第K个数
- 二分求两个有序数组第k大的数
- 如何求两个有序数组的第K个数
- 求两个有序数组的第k小元素
- HDU 4006 求第k大数 treap
- 有序数组a,b,找出a,b(合并为一个大的有序数组后)中第k个数
- 求两个有序数组的中位数(扩展求第k大元素)
- 两个有序数组寻找合并之后第k大的数
- Unity3D入门(一):环境搭建
- MySQL 请选择合适的列!
- java数组的理解
- Linux查看磁盘目录占用大小
- 二叉树 3
- Codevs_P3299 有序数组合并求第K大问题(Treap)
- 哈理工OJ 1305 /POJ 2007 多边形 Scrambled Polygon【计算几何】【极角排序】
- MySQL 基本操作
- JAVA ClassLoader
- Android身份证号码验证
- 重学JavaScript(词法结构扫盲点)
- Python特殊语法这之:filter、map、reduce、lambda
- Weblogic 10.3.5在64位Windows系统下的安装和配置
- WhdeLocalized--针对国际化做的类,可以在应用程序中选择跟随系统,简体,繁体