zoukankan      html  css  js  c++  java
  • 主席树

    主席树节点中维护的值,是([x,y])之间这个区间内数字出现了的次数

    利用可持久化线段树的性质来进行查询,如查询区间([2,5]),即将版本五和版本一对应节点相减,即为([2, 5])内某个范围内的数字的个数

    对于一个区间([l, r]),每次算出在([l, mid])范围内的数字个数,如果数量$ geqslant k (()k(就是第)k$小),就去查询左子树,否则就去查询右子树

    (code :)

    void build(int L,int R,int &cur)
    {
    	cur=++tree_cnt;
    	if(L==R) return;
    	int mid=(L+R)>>1;
    	build(L,mid,ls[cur]);
    	build(mid+1,R,rs[cur]);
    }
    void modify(int L,int R,int pos,int pre,int &cur)
    {
    	cur=++tree_cnt;
    	ls[cur]=ls[pre],rs[cur]=rs[pre];
    	val[cur]=val[pre]+1;
    	if(L==R) return;
    	int mid=(L+R)>>1;
    	if(pos<=mid) modify(L,mid,pos,ls[pre],ls[cur]);
    	if(pos>mid) modify(mid+1,R,pos,rs[pre],rs[cur]);
    }
    int query(int L,int R,int x,int y,int rnk)
    {
    	if(L==R) return L;
    	int num=val[ls[y]]-val[ls[x]],mid=(L+R)>>1;
    	if(num>=rnk) return query(L,mid,ls[x],ls[y],rnk);
    	else return query(mid+1,R,rs[x],rs[y],rnk-num);
    }
    
    ......
    
    build(1,n,root[0]);
    for(int i=1;i<=n;++i) modify(1,n,a[i],root[i-1],root[i]);//建树
    
    rev[query(1,n,root[l-1],root[r],k)]//查询
    
  • 相关阅读:
    SQL 运算符
    Shiro 入门
    SSM 整合配置
    MyBatis 入门
    Git 常用命令
    JSP
    Servlet
    Oracle 基础
    JDBC
    Java Thread
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229518.html
Copyright © 2011-2022 走看看