强大的主席树

以很小的空间相当于建立了n棵线段树,进行查询区间第k小 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn= 2e5 + 100;
struct hyq{
    int l,r,sum;
}T[maxn*40];
int a[maxn], b[maxn],A[maxn];
int root[maxn];
int n,q,cnt;
void ins(int &u,int l,int r,int p){
    T[++cnt]=T[u];
    u=cnt;
    if(l==r){
        T[u].sum++;
        return;
    }
    int mid=(l+r)/2;
    if(p<=mid) ins(T[u].l,l,mid,p);
    else ins(T[u].r,mid+1,r,p);
    T[u].sum=T[T[u].l].sum+T[T[u].r].sum;
}
int query(int lt,int rt,int l,int r,int k){
    if(l==r) return l;
    int mid=(l+r)/2;
    int t=T[T[rt].l].sum-T[T[lt].l].sum;
    if(k<=t) return query(T[lt].l,T[rt].l,l,mid,k);
    else return query(T[lt].r,T[rt].r,mid+1,r,k-t);
}
int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        A[i]=a[i];
    }
    sort(A+1,A+n+1);
    A[0]=unique(A+1,A+n+1)-A-1;
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(A+1,A+A[0]+1,a[i])-A;
    }
    root[0]=0;
    for(int i=1;i<=n;i++){
        root[i]=root[i-1];
        ins(root[i],1,A[0],a[i]);
    }
    for(int i=1;i<=q;i++){
        int ll,rr,kk;
        scanf("%d%d%d",&ll,&rr,&kk);
        cout<<A[query(root[ll-1],root[rr],1,A[0],kk)]<<endl;
    }
    
}

访问历史版本的主席树 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1001010;
struct node{
    int l,r,sum;
}T[maxn*30];
int read(){
    char c=getchar();
    int x=0,f=1;
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
int n,m,cnt;
int A[maxn],a[maxn],root[maxn];
void build(int &u,int l,int r){
    u=++cnt;
    if(l==r){
        T[u].sum=a[l];
        return;
    } 
    int mid=(l+r)/2;
    build(T[u].l,l,mid);
    build(T[u].r,mid+1,r);
}
void ins(int &u,int last,int l,int r,int x,int v){
    u=++cnt;
    T[u]=T[last];
    if(l==r){
        T[u].sum=v;
        return;
    }
    int mid=(l+r)/2;
    if(x<=mid) ins(T[u].l,T[last].l,l,mid,x,v);
    else ins(T[u].r,T[last].r,mid+1,r,x,v);
}
int query(int o,int l,int r,int p){
    if(l==r) return T[o].sum;
    int mid=(l+r)/2;
    if(p<=mid) return query(T[o].l,l,mid,p);
    else return query(T[o].r,mid+1,r,p);
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        //A[i]=a[i];
    }
    /*sort(A+1,A+N+1);
    A[0]=unique(a+1,a+n+1)-a-1;
    for(int i=1;i=n;i++){
        a[i]=lower_bound(A+1,a+A[0]+1,a[i])-A;
    }*/
    root[0]=0;
    build(root[0],1,n);
    for(int i=1;i<=m;i++){
        
        int v,p,loc,val;
        v=read();
        p=read();
        loc=read();
        if(p==1){
            val=read();
            ins(root[i],root[v],1,n,loc,val);
        }
        if(p==2){
            cout<<query(root[v],1,n,loc)<<endl;
            root[i]=root[v];
        }	
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42759194/article/details/81809016
今日推荐