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

    静态主席树

    #include<bits/stdc++.h>
    using namespace std;
    #define mid ((l+r)>>1)
    const int MAXN=10;
    int n,m,a[MAXN],b[MAXN],N;
    //a为原数组,b为离散后的数组,N为离散后的个数
    int root[MAXN],sum[MAXN<<5],node_num;
    //root[i]:插入i个节点后的树的编号
    //sum[i]:节点i代表的区间内数字出现的次数
    int lson[MAXN<<5],rson[MAXN<<5];
    //lson[i]:编号为i的节点的左儿子编号
    int build(int l,int r){
        int num=++node_num;
        if(l^r){
            lson[num]=build(l,mid);
            rson[num]=build(mid+1,r);
        }
        return num;
    }
    int update(int pre,int l,int r,int v){
        int num=++node_num;
        lson[num]=lson[pre];
        rson[num]=rson[pre];
        sum[num]=sum[pre]+1;
        if(l^r){
            if(v<=mid)lson[num]=update(lson[pre],l,mid,v);
            else rson[num]=update(rson[pre],mid+1,r,v);
        }
        return num;
    }
    int query(int x,int y,int l,int r,int k){
        if(l==r)return b[l];
        int num=sum[lson[y]]-sum[lson[x]];
        if(k<=num)return query(lson[x],lson[y],l,mid,k);
        else return query(rson[x],rson[y],mid+1,r,k-num);
    }
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){scanf("%d",a+i);b[i]=a[i];}
        sort(b+1,b+n+1);
        N=unique(b+1,b+1+n)-b-1;
        root[0]=build(1,N);
        for(int i=1;i<=n;++i){
            int v=lower_bound(b+1,b+1+N,a[i])-b;
            root[i]=update(root[i-1],1,N,v);
        }
        int x,y,k;
        while(m--){
            scanf("%d%d%d",&x,&y,&k);
            printf("%d
    ",query(root[x-1],root[y],1,N,k));
        }
        return 0;
    }
    
  • 相关阅读:
    ORACLE 计算时间相减间隔
    oracle中游标详细用法
    oracle中计算某月的天数
    Unity3D导出的EXE不用显示分辨率选择界面
    Unity3D 之暂停和继续的实现
    double的值太大,以及补0
    Unity3D鼠标点击物体产生事件
    java POi excel 写入大批量数据
    Unity3D 判断鼠标是否按在UGUI上
    Unity3D 之UGUI 滚动条
  • 原文地址:https://www.cnblogs.com/foursmonth/p/14161826.html
Copyright © 2011-2022 走看看