zoukankan      html  css  js  c++  java
  • sw抄来的主席树

    //本模板是离散后对权值建树
    #include<bits/stdc++.h>
    #define mid (l+r>>1)
    using namespace std;
    const int N=2e5+10;
    struct TR
    {
        int sum,lo,ro;
    }tr[N<<5];
    int tr_cnt;//之后需要初始化=0
    int n,m,q,arr[N],brr[N],rt[N];//m是权值的数量
    void build(int &o,int l=1,int r=m)
    {
        o=++tr_cnt;
        //tr[o].sum=0;
        if(l==r)return;
        build(tr[o].lo,l,mid);
        build(tr[o].ro,mid+1,r);
    }
    void update(int p,int v,int pre,int &o,int l=1,int r=m)
    {
        o=++tr_cnt;
        tr[o]=tr[pre];
        tr[o].sum+=v;//都是+1
        if(l==r)return;
        if(p<=mid)update(p,v,tr[pre].lo,tr[o].lo,l,mid);
        else update(p,v,tr[pre].ro,tr[o].ro,mid+1,r);
    }
    //u和v是两个线段树的根,相减后的线段树求第k个的下标位置
    int query(int k,int u,int v,int l=1,int r=m)
    {
        if(l==r)return l;
     
        int tmp=tr[tr[v].lo].sum-tr[tr[u].lo].sum;
        if(tmp>=k)return query(k,tr[u].lo,tr[v].lo,l,mid);
        else return query(k-tmp,tr[u].ro,tr[v].ro,mid+1,r);
    }
    int main()
    {
        int n,q;scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)scanf("%d",arr+i),brr[i]=arr[i];
        sort(brr+1,brr+1+n);
        m=unique(brr+1,brr+1+n)-brr-1;
     
        build(rt[0]);
        for(int i=1;i<=n;i++)
        {
            int p=lower_bound(brr+1,brr+1+m,arr[i])-brr;
            update(p,1,rt[i-1],rt[i]);
        }
        while(q--)
        {
            int u,v,k;
            scanf("%d%d%d",&u,&v,&k);
            printf("%d
    ",brr[query(k,rt[u-1],rt[v])]);
        }
    	return 0;
    }
    

      

    rush!
  • 相关阅读:
    androd Eclipse Ant 批量打包
    Eclipse中不显示Ant,如何操作
    android Eclipse 多渠道打包
    Android 关于tools
    (转)android studio 使用的主要操作
    Android的NDK开发步骤
    AnimatorSet中before与after的理解
    (转)Android webview 调用相机和照片库 实现文件的上传
    混淆的小记录
    Xamarin.Forms on WPF (Win7)
  • 原文地址:https://www.cnblogs.com/LH2000/p/14659789.html
Copyright © 2011-2022 走看看