静态(非带修)主席树模板(可持久化权值线段树)

静态(非带修)主席树模板(可持久化权值线段树)

洛谷上的主席树模板题
写完后可以自己去交一下,数据已经优化过,必须用主席树写。

接下来是我自己的模板

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;

int w[N],s[N],rk[N],root[N];
int n,m,size,cnt=0;

struct President_tree
{
    int ls,rs,sum;
}t[N*20];

void build(int &node ,int l,int r)
{
    node=++cnt;
    if(l==r)
        return ;
        int mid=(l+r>>1);
    build(t[node].ls,l,mid);
    build(t[node].rs,mid+1,r);
}

void update(int &node,int last ,int l,int r,int s)
{
    node=++cnt;
    t[node]=t[last];
    ++t[node].sum;
    if(l==r)
        return ;
    int mid=(l+r>>1);
    if(s<=mid) update(t[node].ls,t[last].ls,l,mid,s);
    else update(t[node].rs,t[last].rs,mid+1,r,s);
}

int query(int &node ,int last ,int l,int r,int k)
{
    if(l==r) return s[l];
    int sum=t[t[node].ls].sum-t[t[last].ls].sum;
    int mid=(l+r>>1);
    if(k<=sum) return  query(t[node].ls,t[last].ls,l,mid,k);
    else return query(t[node].rs,t[last].rs,mid+1,r,k-sum);
}

int main()
{
    int x,y,k;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    memcpy(s,w,sizeof(s));
    sort(s+1,s+n+1);
    size=unique(s+1,s+n+1)-s-1;//离散化
    build(root[0],1,size);
    for(int i=1;i<=n;i++)
        rk[i]=lower_bound(s+1,s+size+1,w[i])-s;
    for(int i=1;i<=n;i++)
        update(root[i],root[i-1],1,size,rk[i]);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&k);
        printf("%d\n",query(root[y],root[x-1],1,size,k));
    }
    return 0;
}

我认为这是挺清楚的一个静态主席树模板了。

猜你喜欢

转载自blog.csdn.net/weixin_45963335/article/details/107772299