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!
  • 相关阅读:
    Windows Terminal 配色方案说明
    Windows Terminal 美化简记
    家庭组网启用 NAS
    Eclipse使用Git检出项目
    SVN clean失败解决方法
    httpClient closeableHttpClient
    JSON字符串与Map互转
    httpclient用getStatusCode
    同一台电脑同时装jdk1.8和jdk1.7
    PL/SQL连接远程oracle数据库配置
  • 原文地址:https://www.cnblogs.com/LH2000/p/14659789.html
Copyright © 2011-2022 走看看