最小值(划分树)
来源:互联网 发布:js把date转换成字符串 编辑:程序博客网 时间:2024/06/06 18:41
最小值
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
输入N个数,M次查询。
每次查询给出一个数x。
要求:每次查询输出前x个数中第i小的数。(i为第i次查询)
你可以假设M <= N,Xi <= Xi+1 <= Xi+2 <= ……. <= Xm (Xm <= N).
- 输入
- Line0:T
Line1: N,M
Line2…LineN+1:num1,......,numN
LineN+2…LineN+2+M:x1,……,xM
N < 30000, num < 2000000000 - 输出
- 每次查询输出前i小的数,单独一行。
详细格式请参考样例。 - 样例输入
17 43 1 -4 2 8 -1000 21 2 6 6
- 样例输出
3312
- 来源
- STL
- 上传者
- ACM_钟诗俊
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#define maxn 100010#define mid ((l+r)>>1)using namespace std;int t[20][maxn],sum[20][maxn];int a[maxn],as[maxn];//以下为查找区间第k小划分树void build(int p,int l,int r){ int lm=0,i,ls=l,rs=mid+1;//lm表示应被放入左子树且与中位数相等的数有多少个,ls为左子树的起始位置,rs为右子树的起始位置 for(i=mid;i>=l;i--) //求lm { if(as[i]==as[mid]) lm++; else break; } for(i=l;i<=r;i++) { if(i==l)//这里要特殊讨论 sum[p][i]=0; else sum[p][i]=sum[p][i-1]; if(t[p][i]==as[mid])//若与中位数相等则判断是否应该被放入左子树 { if(lm) { lm--; sum[p][i]++; t[p+1][ls++]=t[p][i]; } else t[p+1][rs++]=t[p][i]; } else if(t[p][i]<as[mid])//查找区间第K大即为> { sum[p][i]++; t[p+1][ls++]=t[p][i]; } else t[p+1][rs++]=t[p][i]; } if(l==r) return; build(p+1,l,mid); build(p+1,mid+1,r);}int query(int p,int l,int r,int ql,int qr,int k){ int s,ss;//s表示l到ql-1的区间内放入左子树的个数,ss表示区间[ql,qr]被放入左子树的个数 if(l==r)//找到所求的数 return t[p][l]; if(ql==l) s=0,ss=sum[p][qr]; else s=sum[p][ql-1],ss=sum[p][qr]-s; if(k<=ss)//要找的数在左子树中 return query(p+1,l,mid,l+s,l+sum[p][qr]-1,k); else//要找的数在右子树中 return query(p+1,mid+1,r,mid+1-l+ql-s,mid+1-l+qr-sum[p][qr],k-ss);}int main(){ int t1,n,m,i,b; cin>>t1; while(t1--) { cin>>n>>m; for(i=1;i<=n;i++) { cin>>as[i]; t[0][i]=as[i]; } sort(as+1,as+1+n); build(0,1,n); for(i=1;i<=m;i++) { scanf("%d",&b); cout<<query(0,1,n,1,b,i)<<endl; } }}
0 0
- 最小值(划分树)
- HDU 3473-Minimum Sum(划分树-求区间sigma最小值)
- (1544): 序列划分(求极大值的最小值)&(1233): 【基础算法】 书的复制
- codeforce Maximum of Maximums of Minimums(区间划分 求区间最小值最大值问题)
- hdu2665(划分树)
- hdu 3473(划分树)
- hdu4417(划分树)--二分
- 划分树(模板)poj2104
- Kth number(划分树)
- hdu 2665(划分树)
- hdu 4417(划分树)
- nyoj1185最大最小值(线段树)
- nyoj--1185--最大最小值(线段树)
- nyoj 1185 最大最小值 (线段树)
- Balanced Lineup(线段树+最大值,最小值)
- 划分树
- 【划分树】
- 划分树
- oc知识点整理
- 关于类的关键词
- Hyperion 的oce创建
- Mac系统中强制删除废纸篓文件
- 栈的应用
- 最小值(划分树)
- Leetcode-Sudoku Solver
- 面向对象编程之异常处理
- 性能分析命令详解
- 2.如何创建Activity,启动下一个activity
- CString中Format函数与格式输入与输出
- iOS开发-MJRefresh 上下拉刷新快速集成
- HashMap遍历的两种方式,推荐使用entrySet()
- 暑假选拔赛02 ---- Ysequence