[POJ2104] 主席树模板题
2017-07-17 09:06
260 查看
第一次写主席树,比较畏惧,害怕又会因为一些小错误调试半天,就拿这玩意当模板题写了,然而并没有想象的困难。
随便写什么树一眼望过去全是
题目大意:给你一串数字,每次询问区间[L,R]的第K大
就是要注意建树的时候,后一个节点相对于前一个节点的树实际上只改动了一条链,或者说只有一条链与前一棵树不同。
如果元素要进左子树的话,右子树就会跟上个树这个区间的右子树是完全一样的,因此,可以直接将本树本节点的右子树指针接到上棵树当前节点的右儿子,这样即省时间,又省空间。
from Oyking cnblogs
细节看代码。
抱怨几句
指针的写法要判NULL真的麻烦= =随便写什么树一眼望过去全是
if(XXXX!=NULL)
关于题目
题目连接:POJ2104题目大意:给你一串数字,每次询问区间[L,R]的第K大
分析与思路
感觉没有什么可以说的····就是要注意建树的时候,后一个节点相对于前一个节点的树实际上只改动了一条链,或者说只有一条链与前一棵树不同。
如果元素要进左子树的话,右子树就会跟上个树这个区间的右子树是完全一样的,因此,可以直接将本树本节点的右子树指针接到上棵树当前节点的右儿子,这样即省时间,又省空间。
from Oyking cnblogs
细节看代码。
代码
Problem: 2104 User: Nafario Memory: 49140K Time: 2469MS Language: C++ Result: Accepted #include<algorithm> #include<cstring> #include<cstdio> #include<iostream> using namespace std; int N , M ; struct node{ int siz ; node *ls , *rs ; node(){ ls = rs = NULL ; siz = 0 ; } void update(){ siz = 0 ; if(ls) siz += ls->siz ; if(rs) siz += rs->siz ; } }w[200005 * 20] , *tw = w , *root[200005] ; int ori[200005] , ns[200005] , arcns[200005] , so[200005] , siz ; void read_uniq(){ for( int i = 1 ; i <= N ; i ++ ){ scanf( "%d" , &ori[i] ) ; so[i] = ns[i] = ori[i] ; } sort ( so + 1 , so + N + 1 ) ; siz = unique( so + 1 , so + N + 1 ) - so - 1 ; for( int i = 1 ; i <= N ; i ++ ){ ns[i] = lower_bound( so + 1 , so + siz + 1 , ns[i] ) - so ; arcns[ ns[i] ] = ori[i] ; } } void Insert( node *&las , node *&nd , int lf , int rg , int val ) { nd = ++tw ; las = ( las == NULL ? &w[0] : las ) ; *nd = node(); //printf( "nd = %d lf = %d rg = %d val = %d\n" ,nd , lf , rg , val ) ; int mid = ( lf + rg ) >> 1 ; if( lf == rg ){ *nd = *las ; nd->siz ++ ; return ; } else if( val <= mid ){ Insert( las->ls , nd->ls , lf , mid , val ) ; nd->rs = las->rs ; } else { Insert( las->rs , nd->rs , mid + 1 , rg , val ) ; nd->ls = las->ls ; } nd->update() ; } int Query( node* &Lnd , node* &Rnd , int lf , int rg , int k){ if( lf == rg ) return lf ; //printf("%d %d lf = %d rg = %d\n k = %d" , Lnd , Rnd , lf , rg , k) ; Lnd = ( Lnd == NULL ? &w[0] : Lnd ) ; //Rnd = ( Rnd == NULL ? &w[0] : Rnd ) ; int Lt = 0 ; if( Rnd->ls ) Lt += Rnd->ls->siz ; if( Lnd->ls ) Lt -= Lnd->ls->siz ; //printf("Lt = %d\n" , Lt) ; int mid = ( lf + rg ) >> 1 ; if( k > Lt ) return Query( Lnd->rs , Rnd->rs , mid + 1 , rg , k - Lt ) ; else return Query( Lnd->ls , Rnd->ls , lf , mid , k ) ; } void solve(){ int L , R , k ; w[0] = node() ; for( int i = 1 ; i <= N ; i ++ ) Insert( root[i - 1] , root[i] , 1 , siz , ns[i] ); for( int i = 1 ; i <= M ; i ++ ){ scanf( "%d%d%d" , &L , &R , &k ) ; printf( "%d\n", arcns[ Query( root[ L - 1 ] , root[R] , 1 , siz , k ) ] ); } } int main(){ std::ios::sync_with_stdio(false); scanf( "%d%d" , &N , &M ) ; read_uniq() ; solve() ; return 0 ; }
相关文章推荐
- poj2104 K-th Number【主席树模板】
- [POJ2104] K-th Number(区间K小数,主席树模板)
- poj2104 K-th Number (主席树入门题|模板题)
- 主席树模板(poj2104)
- 主席树模板题-poj2104
- POJ2104-- K-th Number(主席树静态区间第k大)
- [POJ2104]K-th Number 做题笔记 主席树
- 主席树模板(区间第k大!)hdu2665
- poj 2104 K-th Number (主席树模板)
- AC的故事大结局悲剧版(下) 主席树模板,区间修改
- [poj2104]K-th Number 主席树
- 【CQOI2015】任务查询系统 主席树模板题
- [POJ2104]K-th Number(主席树+讲解+可持久化基础)
- poj2104 K-th Number(主席树)
- 主席树——模板整理
- 【模板】可持久化线段树 1(主席树)
- 洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)
- 【POJ2104】K-th Number(主席树)
- 主席树模板
- poj2104(主席树)