可持久化数组
Posted Halifuda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可持久化数组相关的知识,希望对你有一定的参考价值。
#include<cstdio> #define MXN 1000000+1 #define mid(a,b) ((a+b)>>1) int read(){ int x=0,w=1; char c=getchar(); while(c<‘0‘||c>‘9‘){ if(c==‘-‘) w=-1; c=getchar(); } while(c>=‘0‘&&c<=‘9‘){ x=(x<<3)+(x<<1)+(c-‘0‘); c=getchar(); } return x*w; } int arr[MXN]; unsigned int num,q; struct Node{ int val; Node *left,*right; }node[23*MXN],*root[MXN]; int node_num=-1,rtop=-1; void update(Node *now){ Node *nl,*nr; nl=now->left; nr=now->right; if(nl!=NULL) now->val=nl->val; if(nr!=NULL) now->val=nr->val; return; } Node* newnode(){ Node *n; n=&node[++node_num]; n->val=0; n->left=NULL; n->right=NULL; return n; } Node* newnode(Node *now){ Node *n; n=&node[++node_num]; n->val=now->val; n->left=now->left; n->right=now->right; return n; } void build(Node *now,int bl,int br){ if(bl==1&&br==num) root[++rtop]=now; if(bl==br){ now->val=arr[bl]; return; } Node *nl,*nr; nl=newnode(); nr=newnode(); now->left=nl; now->right=nr; build(nl,bl,mid(bl,br)); build(nr,mid(bl,br)+1,br); update(now); return; } Node* change(Node *now,int k,int al,int ar,int l,int r){ if(l>ar||r<al) return NULL; Node *n; if(l<=al&&ar<=r){ n=newnode(now); } if(al<=l&&r<=ar){ n->val=k; } else{ Node *ls,*rs; ls=n->left; rs=n->right; if(n->left!=NULL&&l<=al&&ar<=mid(l,r)){ n->left=newnode(ls); n->left=change(n->left,k,al,ar,l,mid(l,r)); } if(n->right!=NULL&&mid(l,r)+1<=al&&ar<=r){ n->right=newnode(rs); n->right=change(n->right,k,al,ar,mid(l,r)+1,r); } update(n); } if(l==1&&r==num) root[++rtop]=n; return n; } Node* ques(Node *now,int ql,int qr,int l,int r){ if(r<ql||qr<l) return now; Node *n; if(l<=ql&&qr<=r){ n=newnode(now); } if(ql<=l&&r<=qr) return n; Node *ls,*rs; ls=n->left; rs=n->right; if(n->left!=NULL&&l<=ql&&qr<=mid(l,r)){ n->left=newnode(ls); n->left=ques(n->left,ql,qr,l,mid(l,r)); } if(n->right!=NULL&&mid(l,r)+1<=ql&&qr<=r){ n->right=newnode(rs); n->right=ques(n->right,ql,qr,mid(l,r)+1,r); } update(n); if(l==1&&r==num) root[++rtop]=n; return n; } int find(Node *now,int ql,int qr,int l,int r){ if(r<ql||qr<l) return 0; if(ql<=l&&r<=qr) return now->val; if(now->left!=NULL&&l<=ql&&qr<=mid(l,r)){ return find(now->left,ql,qr,l,mid(l,r)); } if(now->right!=NULL&&mid(l,r)+1<=ql&&qr<=r){ return find(now->right,ql,qr,mid(l,r)+1,r); } } int main(){ num=read(); q=read(); for(int i=1;i<=num;i++) arr[i]=read(); build(newnode(),1,num); for(int i=0;i<q;i++){ int edt,p,a,b; edt=read(); p=read(); if(p==1){ a=read(); b=read(); change(root[edt],b,a,a,1,num); } if(p==2){ a=read(); ques(root[edt],a,a,1,num); printf("%d\n",find(root[rtop],a,a,1,num)); } } return 0; }
我交的题是洛谷P3919。
我要谴责一下这道题。
我写的是指针。
MLE了。
mmp。
就不能照顾一下指针党吗。
调了一天。
我上面的代码是提交效果最好的一次。
23,1000000+1这两个参数是我二分出来的,只有这组可以MLE两个点,其他参数会RE。
虽然爆粗很对不起,但是我现在心态爆炸了,所以大家容忍一下。
以上是关于可持久化数组的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ2112 Dynamic Rank(可持久化线段树套树状数组)
ZOJ2112 Dynamic Rank(可持久化线段树套树状数组)