poj 2588
来源:互联网 发布:炒股模拟软件app 编辑:程序博客网 时间:2024/06/05 02:57
题意:给你一个长度为n的数列,以及m个形如l r k的询问,即求出区间【l,r】中第k小的值
分析:考虑最简单的想法,可以建立n棵权值线段树来维护,但显然空间会承受不了。这个时候可以发现每一次建立一棵新的线段树,事实上有很多子树是和上一棵树重复的,所以可以直接利用上一棵树的某些节点。每次最多增加logn个节点,空间复杂度最终为nlogn。
技能:空间大小不能开错。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(i,a,b) for (int i=a;i<=b;++i)
#define N 100010
int ls[N*30],rs[N*30],size[N*30],hash[N],root[N],a[N],num[N];
int n,m,sz,tot;
int read()
{
int f=1,x=0;char ch=getchar();
for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
}
void insert(int l,int r,int x,int &y,int k)
{
size[y=++sz]=size[x]+1;// size为数的个数
if (l==r) return;
int mid=l+r>>1;
rs[y]=rs[x]; ls[y]=ls[x];
if (a[k]<=hash[mid]) insert(l,mid,ls[x],ls[y],k);
else insert(mid+1,r,rs[x],rs[y],k);
}
int query(int l,int r,int x,int y,int k)
{
if (l==r) return l;
int mid=l+r>>1;
if (k<=size[ls[y]]-size[ls[x]]) return query(l,mid,ls[x],ls[y],k);
else return query(mid+1,r,rs[x],rs[y],k-size[ls[y]]+size[ls[x]]);
}
int main()
{
n=read(); m=read();
rep(i,1,n) a[i]=read(),num[i]=a[i];
sort(num+1,num+n+1);
hash[++tot]=num[1];
rep(i,2,n) if (num[i]^num[i-1]) hash[++tot]=num[i];// 离散化
rep(i,1,n) insert(1,tot,root[i-1],root[i],i);//逐个加入点,并以上一个根结点为基础构建线段树
rep(i,1,m)
{
int u=read(),v=read(),x=read();
printf("%d\n",hash[query(1,tot,root[u-1],root[v],x)]);
}
return 0;
}
- poj 2588
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- Mybatis逆向生成文件
- 【机房重构】-C#注册
- jzoj. 3505. 【NOIP2013模拟11.4A组】积木(brick)
- 关于UITextField左侧图标的设置
- UVa401-Palindromes-回文词-字符函数,常量数组
- poj 2588
- android之服务service远程服务
- webpack+vue 实现多页面开发
- 05.15 三剑客之老四find命令详解
- dva -react TypeError: root.findRouters(...).getRouterInfo is not a function
- 关于在Windows10 Eclipse 配置Dos(cmd)窗口
- [Microsoft] Identical Binary Tree
- 简单粒子群优化算法的函数寻优
- 基于类实现的简易计算器