落谷 P3834 可持久化线段树 1(主席树)(区间第k小)

设区间为l,r,用r版本减去l版本求出区间第k小,一个板子

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct node1
{
    int v;
    int po;
}ed[500005];
struct node2
{
    int v;
    int vy;
}ed2[500005];
int cmp(node1 a,node1 b)
{
    return a.v<b.v;
}
int cnt;
int root[500005];
int tval[500005];
struct Tree
{
    int lson;
    int rson;
    int val;
}tree[500005*30];
void insert(int &rt,int ort,int l,int r,int po,int val)
{
    if(!rt)rt=++cnt;
    if(l==r)
    {
        tree[rt].val=tree[ort].val+val;
        return;
    }
    int mid=(l+r)/2;
    if(po<=mid)
    {
        tree[rt].rson=tree[ort].rson;
        insert(tree[rt].lson,tree[ort].lson,l,mid,po,val);
    }else
    {
        tree[rt].lson=tree[ort].lson;
        insert(tree[rt].rson,tree[ort].rson,mid+1,r,po,val);
    }
    tree[rt].val=tree[tree[rt].lson].val+tree[tree[rt].rson].val;
}
int query(int rt,int ort,int l,int r,int k)
{
    if(!rt)return 0;
    int mid=(l+r)/2;
    if(l==r)
    {
        return l;
    }
    if(k<=tree[tree[rt].lson].val-tree[tree[ort].lson].val)
    {
        return query(tree[rt].lson,tree[ort].lson,l,mid,k);
    }else
    {
        k-=tree[tree[rt].lson].val-tree[tree[ort].lson].val;
        return query(tree[rt].rson,tree[ort].rson,mid+1,r,k);
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",&ed[i].v);
        ed[i].po=i;
    }
    sort(ed+1,ed+1+n,cmp);
    int tt=1;
    ed2[ed[1].po].v=1;
    ed2[ed[1].po].vy=ed[1].v;
    for(int i = 2;i <= n;i++)
    {
        if(ed[i].v!=ed[i-1].v)
        {
            ed2[ed[i].po].v=++tt;
            ed2[ed[i].po].vy=ed[i].v;
        }else
        {
            ed2[ed[i].po].v=tt;
            ed2[ed[i].po].vy=ed[i].v;
        }
    }
    for(int i = 1;i <= n;i++)
    {
        insert(root[i],root[i-1],1,tt,ed2[i].v,1);
        tval[ed2[i].v]=ed2[i].vy;
    }
    for(int i = 1;i <= m;i++)
    {
        int a,b,kk;
        scanf("%d%d%d",&a,&b,&kk);
        int ty=query(root[b],root[a-1],1,tt,kk);
        printf("%d\n",tval[ty]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zzk_233/article/details/82821457