您的位置:首页 > 其它

【模板】可持久化线段树(主席树)

2017-12-15 19:51 337 查看
当修改线段树产生新的版本时,对于不需要修改的区间,直接指向原有的点,需要修改的区间,建立新点并连过去。 所以只需要维护m棵线段树的根,动态开点就可以了。

【模板】可持久化数组(可持久化线段树/平衡树) 洛谷P3919

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct Node{
int val;
Node *ch[2];
}*root
;
int n,m,a
;
void build(Node *&root,int L,int R){
root=new Node;
if(L==R){
root->val=a[L];
return;
}
int mid=L+R>>1;
build(root->ch[0],L,mid);
build(root->ch[1],mid+1,R);
}
void insert(Node* &root,int L,int R,int loc,int val){
Node *tmp=root;
root=new Node;
root->ch[0]=tmp->ch[0];
root->ch[1]=tmp->ch[1];
if(L==R)    {root->val=val;return;}
int mid=L+R>>1;
if(loc<=mid)    insert(root->ch[0],L,mid,loc,val);
else            insert(root->ch[1],mid+1,R,loc,val);
}
int Query(Node *root,int L,int R,int loc){
if(L==R)    return root->val;
int mid=L+R>>1;
if(loc<=mid)    return Query(root->ch[0],L,mid,loc);
else            return Query(root->ch[1],mid+1,R,loc);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)   scanf("%d",&a[i]);
build(root[0],1,n);
for(int i=1;i<=m;++i){
int ver,opt;
scanf("%d%d",&ver,&opt);
root[i]=root[ver];
if(opt==1){
int loc,val;
scanf("%d%d",&loc,&val);
insert(root[i],1,n,loc,val);
}
else{
int loc;
scanf("%d",&loc);
printf("%d\n",Query(root[i],1,n,loc));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: