POJ 2104 静态找区间第k大
2015-08-27 10:32
267 查看
静态区间第k大的问题,往往可以利用主席树来解决
这是主席树的第一道题
主席树大概可以理解为在n个节点上都建立一棵线段树,但是想想会超出内存
每一个节点保存的线段树都记录当前整段前缀区间的信息
但是因为每次添加后一个节点,那么他除了当前节点位置需要更新之外,其他的位置都可以保持跟上一棵节点对应的线段树一致,那么为了缩小内存,
将那些不需要改变的点的指针指向上一棵树对应的节点即可,其他多生成的节点也就是需要更新的节点,最多不超过log2n个,所以最后产生的线段树的
点的个数大概在nlogn的大致范围内
这是主席树的第一道题
主席树大概可以理解为在n个节点上都建立一棵线段树,但是想想会超出内存
每一个节点保存的线段树都记录当前整段前缀区间的信息
但是因为每次添加后一个节点,那么他除了当前节点位置需要更新之外,其他的位置都可以保持跟上一棵节点对应的线段树一致,那么为了缩小内存,
将那些不需要改变的点的指针指向上一棵树对应的节点即可,其他多生成的节点也就是需要更新的节点,最多不超过log2n个,所以最后产生的线段树的
点的个数大概在nlogn的大致范围内
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define N 100005 #define M int m=(l+r)>>1 #define LS(o) node[o].ls #define RS(o) node[o].rs int n , m , a , b , T ; struct Node{ int sz , ls , rs; void init(){sz=0;ls=rs=0;} }node[N*30]; int tot; int build(int l , int r) { int u = tot++; node[u].init(); if(l!=r){ M; node[u].ls = build(l , m); node[u].rs = build(m+1 , r); } return u; } void build(int o1 , int o2 , int l , int r , int pos) { node[o2].init(); node[o2].sz = node[o1].sz+1; M; if(l == r) return; if(pos<=m){ node[o2].ls = tot++ , node[o2].rs = RS(o1); build(LS(o1) , LS(o2) , l , m , pos); } else { node[o2].rs = tot++ , node[o2].ls = LS(o1); build(RS(o1) , RS(o2) , m+1 , r , pos); } } int query(int o1 , int o2 , int l , int r , int k) { if(l==r) return l; M; int tmp; if((tmp=node[LS(o2)].sz - node[LS(o1)].sz)>=k) return query(LS(o1) , LS(o2) , l , m , k); else return query(RS(o1) , RS(o2) , m+1 , r , k-tmp); } int main() { // freopen("in.txt" , "r" , stdin); while(~scanf("%d%d" , &n , &m)){ for(int i=1 ; i<=n ; i++)scanf("%d" , a+i); for(int i=1 ; i<=n ; i++)b[i]=a[i]; sort(b+1 , b+n+1); tot = 0; T[0] = build(1 , n); for(int i=1 ; i<=n ; i++){ int pos = lower_bound(b+1 , b+n+1 , a[i])-b; T[i] = tot++; build(T[i-1] , T[i] , 1 , n , pos); } while(m--){ int s , t , k; scanf("%d%d%d" , &s , &t , &k); int pos = query(T[s-1] , T[t] , 1 , n , k); printf("%d\n" , b[pos]); } } return 0; }
相关文章推荐
- leetcode--PalindromeLinkedList
- poj-2442Sequence
- 设置listview中item的间距和颜色
- Windows下使用IJL编解码图片
- 算法 —— 堆排序
- 微信公众账号登陆授权开发——3
- kernel如何保证cache数据一致性
- 定义数组类型及数组类型指针
- 微信公众账号登陆授权开发——3
- OAuth授权过程
- Cacti无图无数据等错误解决
- Git 使用规范流程
- Codeforces 460C Present
- Android开发MVP模式解析
- uvalive 6957 Hyacinth 题目难理解
- 【Cactus仙人掌图】仙人掌DP学习笔记
- 算法 —— 归并排序
- 18条心理学定律,值得一看
- python __new__、__init__、__call__
- UITextfield键盘相关设置