1. 程式人生 > >luogu P3919 [模板]可持久化數組(可持久化線段樹/平衡樹)(主席樹)

luogu P3919 [模板]可持久化數組(可持久化線段樹/平衡樹)(主席樹)

build getchar span 否則 \n 一個 odi 端點 當前

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 [模板]可持久化數組(可持久化線段樹/平衡樹)(主席樹)