主席树

#include <bits/stdc++.h>

using namespace std;
const int MAX_N=1e5+10;
struct node
{
int ls,rs,sum;
}tree[MAX_N*40];

int a[MAX_N],p[MAX_N],tr[MAX_N],CNT;

vector<int>ve;

void disc(int n)
{
        for(int i=1;i<=n;i++)
        ve.push_back(a[i]);
        sort(ve.begin(),ve.end());
        unique(ve.begin(),ve.end());
        for(int i=1;i<=n;i++)
        p[i]=lower_bound(ve.begin(),ve.end(),a[i])-ve.begin()+1;
}

void push_up(int p)
{
        tree[p].sum=tree[tree[p].ls].sum+tree[tree[p].rs].sum;
}

int build(int l,int r)
{
        int p=CNT++;
        if(l==r)
        return p;
        int mid=(l+r)/2;
        tree[p].ls=build(l,mid);
        tree[p].rs=build(mid+1,r);
        return p;
}

int insert_tar(int last_p,int l,int r,int tar)
{
        int p=CNT++;
        if(l==r)
        {
                tree[p].sum=tree[last_p].sum+1;
                return p;
        }
        tree[p].ls=tree[last_p].ls;
        tree[p].rs=tree[last_p].rs;
        int mid=(l+r)/2;
        if(tar<=mid)
        tree[p].ls=insert_tar(tree[last_p].ls,l,mid,tar);
        else
        tree[p].rs=insert_tar(tree[last_p].rs,mid+1,r,tar);
        push_up(p);
        return p;
}

int query(int first,int last,int l,int r,int k)
{
        if(l==r)
        return l;
        int t=tree[tree[last].ls].sum-tree[tree[first].ls].sum;
        int mid=(l+r)/2;
        if(k<=t)
        return query(tree[first].ls,tree[last].ls,l,mid,k);
        else
        return query(tree[first].rs,tree[last].rs,mid+1,r,k-t);
}

void init(int n)
{
        CNT=1;
        for(int i=1;i<n*40;i++)
        tree[i].sum=tree[i].ls=tree[i].rs=0;
        tr[0]=build(1,n);
        ve.clear();
}

int main()
{
        int n,m,l,r,k;
        while(~scanf("%d%d",&n,&m))
        {
                init(n);
                for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
                disc(n);
                for(int i=1;i<=n;i++)
                tr[i]=insert_tar(tr[i-1],1,n,p[i]);
                while(m--)
                {
                scanf("%d%d%d",&l,&r,&k);
                printf("%d\n",ve[query(tr[l-1],tr[r],1,n,k)-1]);
                }
        }
    return 0;
}

 

上一篇:【java】求一元二次方程的解


下一篇:103. 二叉树的锯齿形层次遍历