luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)
Posted eternal风度
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)相关的知识,希望对你有一定的参考价值。
luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目
#include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<algorithm> #include<ctime> #include<queue> #include<stack> #define rg register #define il inline #define lst long long #define N 1000050 using namespace std; int n,Q,cnt; int val[N]; int root[N]; struct TREE{ int ls,rs,v; }ljl[N*25]; il int read() { rg int s=0,m=1;rg char ch=getchar(); while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘))ch=getchar(); if(ch==‘-‘)m=-1,ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)s=(s<<3)+(s<<1)+ch-‘0‘,ch=getchar(); return s*m; } il void build(rg int &now,rg int le,rg int ri) //现在所在的点(可往回传参), 左端点, 右端点 { ljl[++cnt]=ljl[now];//新开一个点…… now=cnt;//保证now指的是当点这个点,因为还要传回去赋值给“爸爸的左/右儿子”……具体看后面的递归build if(le==ri){ljl[now].v=val[le];return;}//如果到单点赋值就ojbk了(同线段树) rg int mid=(le+ri)>>1; build(ljl[now].ls,le,mid),build(ljl[now].rs,mid+1,ri); //建造左儿子和右儿子,本节点向他们的指针在递归函数往回传参时会赋值(一切都源于一个美丽的“ & ”) } void Modify(rg int &now,rg int le,rg int ri,rg int kk,rg int x)//很像build //现在所在的点(可往回传参),左端点,右端点,要修改的点编号,修改后的值 { ljl[++cnt]=ljl[now];//又要开点了…… now=cnt;//保证now指的是当点这个点,因为还要传回去赋值给“爸爸的左/右儿子”……具体看后面的递归Modify if(le==ri){ljl[now].v=x;return;}//照样赋值 rg int mid=(le+ri)>>1; if(kk<=mid)Modify(ljl[now].ls,le,mid,kk,x); else Modify(ljl[now].rs,mid+1,ri,kk,x); //kk在mid左边,就建左孩子,否则建右孩子……需要模拟哦…… } int Query(rg int now,rg int le,rg int ri,rg int kk) { if(le==ri)return ljl[now].v; rg int mid=(le+ri)>>1; if(kk<=mid)return Query(ljl[now].ls,le,mid,kk); else return Query(ljl[now].rs,mid+1,ri,kk); } int main() { n=read(),Q=read(); for(rg int i=1;i<=n;++i)val[i]=read(); build(root[0],1,n);//先按原来的值建一棵线段树在0号根上 for(rg int i=1;i<=Q;++i) { rg int edi=read(),type=read();//历史版本edi,询问type if(type==1) { rg int kk=read(),x=read();//把kk号的val改成x root[i]=root[edi];//先把根连过来,再修改! Modify(root[i],1,n,kk,x);//从根开始,左,右端点,修改的编号,修改成的值 } else { rg int kk=read(); printf("%d\n",Query(root[edi],1,n,kk));//当前节点(也就是edi时的根),左,右端点,询问第kk号的值 root[i]=root[edi];//这个依题,还是弄过来吧…… } } return 0; }
以上是关于luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)的主要内容,如果未能解决你的问题,请参考以下文章
[解题报告]P3919 模板可持久化数组(可持久化线段树/平衡树)