1. 程式人生 > >洛谷P2286寵物收養場·改

洛谷P2286寵物收養場·改

() mod val right get splay none 空間復雜度 出現

技術分享圖片
#include<cstdio>
#define abs(a,b) (a>b?a-b:b-a)
#define MOD 1000000
#define MXN 80000+5
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 ans; struct Node{ int val; bool type; Node *fa,*left,*right; }node[MXN],*root,*recycle[MXN]; int n,p,x,node_num=-1,top=-1; bool tree_type; void rotate(Node *now){ if(now->fa==NULL) return; Node *f,*gf,*l,*r; f=now->fa; gf
=f->fa; l=now->left; r=now->right; now->fa=gf; if(gf!=NULL){ if(gf->left==f) gf->left=now; if(gf->right==f) gf->right=now; } if(f->left==now){ now->right=f; f->left=r; if(r!=NULL) r->fa=f; } if
(f->right==now){ now->left=f; f->right=l; if(l!=NULL) l->fa=f; } f->fa=now; if(now->fa==NULL) root=now; return; } void splay(Node *now,Node *des){ if(now==des) return; Node *f,*gf; while(now->fa!=des){ f=now->fa; gf=f->fa; if(gf==des) rotate(now); else if(gf->left==f&&f->right==now){ rotate(now); rotate(now); } else if(gf->right==f&&f->left==now){ rotate(now); rotate(now); } else if(gf->left==f&&f->left==now){ rotate(f); rotate(now); } else if(gf->right==f&&f->right==now){ rotate(f); rotate(now); } } if(now->fa==NULL) root=now; return; } Node* node_new(int vl,bool typ){ Node *n; if(top!=-1){ n=recycle[top]; top--; } else{ node_num++; n=&node[node_num]; } n->val=vl; n->type=typ; n->left=NULL; n->right=NULL; n->fa=NULL; return n; } void node_insert(Node *now,Node *v){ if(root==NULL){ root=v; tree_type=v->type; return; } if(now==NULL){ *now=*v; return; } if(v->val<=now->val){ if(now->left==NULL){ now->left=v; v->fa=now; } else node_insert(now->left,v); } if(v->val>now->val){ if(now->right==NULL){ now->right=v; v->fa=now; } else node_insert(now->right,v); } splay(v,NULL); return; } Node* root_prev(){ Node *t; if(root->left!=NULL){ t=root->left; while(t->right!=NULL) t=t->right; return t; } else return NULL; } Node* root_subs(){ Node *t; if(root->right!=NULL){ t=root->right; while(t->left!=NULL) t=t->left; return t; } else return NULL; } void node_delete(Node *now){ recycle[++top]=now; splay(now,NULL); root=now; if(now->left==NULL&&now->right==NULL){ root=NULL; return; } if(now->left==NULL){ root=now->right; root->fa=NULL; return; } if(now->right==NULL){ root=now->left; root->fa=NULL; return; } Node *l,*r; l=now->left; r=now->right; l->fa=NULL; Node *t=now->left; while(t->right!=NULL) t=t->right; splay(t,NULL); t->right=r; r->fa=t; root=t; return; } void ques(Node *now){ node_insert(root,now); if(now->type==tree_type) return; else{ splay(now,NULL); Node *p,*s,*a; p=root_prev(); s=root_subs(); a=p; int t1,t2; if(p!=NULL) t1=abs(p->val,now->val); else t1=1<<30; if(s!=NULL) t2=abs(s->val,now->val); else t2=1<<30; if(t2<t1){ a=s; ans+=t2; } else ans+=t1; ans%=MOD; node_delete(now); node_delete(a); } return; } int main(){ root=NULL; n=read(); for(int i=0;i<n;i++){ p=read(); x=read(); ques(node_new(x,(bool)p)); } printf("%d",ans); return 0; }
優化代碼

這次修改了一下上次寫的代碼。

由於本人建樹的方法屬於靜態分配內存(動態分配總會出現玄學錯誤...),因此內存空間要開很大很大才不會RE,刪除節點後,上一次的代碼沒有垃圾回收,導致空間復雜度稍大(上一次大約O(5n)才過去)。

這次開了一個棧,命名為recycle回收站,每次刪除節點後,地址丟到回收站,創造新節點時,先檢查回收站裏有沒有空閑地址,有就用,沒有才在靜態內存空間裏找一個地址分配。這樣空間復雜度變為了O(2n),降低了很多(實際上從4.31MB降到了2.21MB)。

不過感覺回頭還是學一下動態分配吧...

洛谷P2286寵物收養場·改