模板:主席树

主席树就是可持久化线段树

求区间K大数:

 

#include<bits.stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int>v;
struct node{
    int l,r,s;
}t[N*40];
int rt[N],a[N],cnt;
int get(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
void update(int l,int r,int x,int &y,int pos){
    y=++cnt;t[y]=t[x];t[y].s++;
    if(l==r)return;
    int m=(l+r)>>1;
    if(pos<=m)update(l,m,t[x].l,t[y].l,pos);
    else update(m+1,r,t[x].r,t[y].r,pos);
}
int query(int l,int r,int x,int y,int num){
    if(l==r)return l;
    int sum=t[t[y].l].s-t[t[x].l].s;
    int m=(l+r)>>1;
    if(sum>=num)return query(l,m,t[x].l,t[y].l,num);
    else return query(m+1,r,t[x].r,t[y].r,num-sum);
}
int main(){
    int n,m;int x,l,r;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)scanf("%d",&a[i]),v.push_back(a[i]);
    sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
    for(int i=1;i<=n;++i)update(1,n,rt[i-1],rt[i],get(a[i]));
    for(int i=1;i<=m;++i){
        scanf("%d%d%d",&l,&r,&x);
        printf("%d\n",v[query(1,n,rt[l-1],rt[r],x)-1]);
    }
    return 0;
}

 

题目描述:

你需要维护这样的一个长度为N的数组,支持如下几种操作

  1. 在某个历史版本上修改某一个位置上的值

  2. 访问某个历史版本上的某一位置的值

此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组

样例输入:

5 10
59 46 14 87 41
0 2 1
0 1 1 14
0 1 1 57
0 1 1 88
4 2 4
0 2 5
0 2 4
4 2 1
2 2 2
1 1 5 91
样例输出:
59
87
41
87
88
46

代码:
#include<bits/stdc++.h>
const int N=1000005;
using namespace std;
int a[N],n,m,q,rt[N*20];
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x;
}
struct Persistable_Segment_Tree{
    int lc[N*20],rc[N*20],val[N*20],cnt;
    inline void build(int &k,int l,int r){
        k=++cnt;
        if(l==r){
			val[k]=a[l];
			return;
		}
        int mid=(l+r)>>1;
        build(lc[k],l,mid);
		build(rc[k],mid+1,r);
    }
    inline void ins(int &k,int pre,int l,int r,int q,int v){
        k=++cnt;
		lc[k]=lc[pre];
		rc[k]=rc[pre];
		val[k]=val[pre];
        if(l==r){
			val[k]=v;
			return;
		}
        int mid=(l+r)>>1;
        if(q<=mid) ins(lc[k],lc[pre],l,mid,q,v);
        else ins(rc[k],rc[pre],mid+1,r,q,v);
    }
    inline int query(int k,int l,int r,int q){
        if(l==r) return val[k];
        int mid=(l+r)>>1;
        if(q<=mid) return query(lc[k],l,mid,q);
        else return query(rc[k],mid+1,r,q);
    }
}T;
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)
		a[i]=read();
    T.build(rt[0],1,n);
    for(int i=1;i<=m;i++){
        int pre=read(),opt=read(),x=read();
        if(opt==1){
			int v=read();
			T.ins(rt[i],rt[pre],1,n,x,v);
		}
        if(opt==2){
			printf("%d\n",T.query(rt[pre],1,n,x));
			rt[i]=rt[pre];
		}
    }
}
posted @ 2019-08-03 18:32  xukl21  阅读(126)  评论(0编辑  收藏  举报