可持久化数组·放弃尊严

#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;
    int left,right;
}node[43*MXN];
int root[MXN];
int node_num=-1,rtop=-1;
void update(int now){
    int nl,nr;
    nl=node[now].left;
    nr=node[now].right;
    if(nl!=-1) node[now].val=node[nl].val;
    if(nr!=-1) node[now].val=node[nr].val;
    return;
}
int newnode(){
    Node *n;
    n=&node[++node_num];
    n->val=0;
    n->left=-1;
    n->right=-1;
    return node_num;
}
int newnode(int now){
    Node *n;
    n=&node[++node_num];
    n->val=node[now].val;
    n->left=node[now].left;
    n->right=node[now].right;
    return node_num;
}
void build(int now,int bl,int br){
    if(bl==1&&br==num) root[++rtop]=now;
    if(bl==br){
        node[now].val=arr[bl];
        return;
    }
    int nl,nr;
    nl=newnode();
    nr=newnode();
    node[now].left=nl;
    node[now].right=nr;
    build(nl,bl,mid(bl,br));
    build(nr,mid(bl,br)+1,br);
    update(now);
    return;
}
int change(int now,int k,int al,int ar,int l,int r){
    if(l>ar||r<al) return -1;
    int n;
    if(l<=al&&ar<=r){
        n=newnode(now);
    }
    if(al<=l&&r<=ar){
        node[n].val=k;
    }
    else{
        int ls,rs;
        ls=node[n].left;
        rs=node[n].right;
        if(node[n].left!=-1&&l<=al&&ar<=mid(l,r)){
            node[n].left=newnode(ls);
            node[n].left=change(node[n].left,k,al,ar,l,mid(l,r));
        }
        if(node[n].right!=-1&&mid(l,r)+1<=al&&ar<=r){
            node[n].right=newnode(rs);
            node[n].right=change(node[n].right,k,al,ar,mid(l,r)+1,r);
        }
        update(n);
    }
    if(l==1&&r==num) root[++rtop]=n;
    return n;
}
int ques(int now,int ql,int qr,int l,int r){
    if(r<ql||qr<l) return now;
    int n;
    if(l<=ql&&qr<=r){
        n=newnode(now);
    }
    if(ql<=l&&r<=qr) return n;
    int ls,rs;
    ls=node[n].left;
    rs=node[n].right;
    if(node[n].left!=-1&&l<=ql&&qr<=mid(l,r)){
        node[n].left=newnode(ls);
        node[n].left=ques(node[n].left,ql,qr,l,mid(l,r));
    }
    if(node[n].right!=-1&&mid(l,r)+1<=ql&&qr<=r){
        node[n].right=newnode(rs);
        node[n].right=ques(node[n].right,ql,qr,mid(l,r)+1,r);
    }
    update(n);
    if(l==1&&r==num) root[++rtop]=n;
    return n;
}
int find(int now,int ql,int qr,int l,int r){
    if(r<ql||qr<l) return 0;
    if(ql<=l&&r<=qr) return node[now].val;
    if(node[now].left!=-1&&l<=ql&&qr<=mid(l,r)){
        return find(node[now].left,ql,qr,l,mid(l,r));
    }
    if(node[now].right!=-1&&mid(l,r)+1<=ql&&qr<=r){
        return find(node[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;
}
放弃尊严

这次我放弃了作为了指针党的尊严,选择了数组实现,A了。

我心情十分的复杂。

不过时间确实并不优秀,可能我主席树写的常数还是太大。

哭了。

不过我以后大约还是会用指针多一些。

posted @ 2017-12-02 16:06  Halifuda  阅读(143)  评论(0编辑  收藏  举报