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

洛谷P2286寵物收養場

get hid amp tchar sub += 別人 節點 tdi

技術分享圖片
  1 #include<cstdio>
  2 #define abs(a,b) (a>b?a-b:b-a)
  3 #define MOD 1000000
  4 #define MXN 450000+5
  5 int read(){
  6     int x=0,w=1;
  7     char c=getchar();
  8     while(c<0||c>9){
  9         if(c==-) w=-1;
 10         c=getchar();
 11     }
 12     while(c>=0&&c<=
9){ 13 x=(x<<3)+(x<<1)+(c-0); 14 c=getchar(); 15 } 16 return x*w; 17 } 18 int ans; 19 struct Node{ 20 int val; 21 bool type; 22 Node *fa,*left,*right; 23 }node[MXN],*root; 24 int n,p,x,node_num=-1,sum; 25 bool tree_type; 26 void rotate(Node *now){
27 if(now->fa==NULL) return; 28 Node *f,*gf,*l,*r; 29 f=now->fa; 30 gf=f->fa; 31 l=now->left; 32 r=now->right; 33 now->fa=gf; 34 if(gf!=NULL){ 35 if(gf->left==f) gf->left=now; 36 if(gf->right==f) gf->right=now; 37
} 38 if(f->left==now){ 39 now->right=f; 40 f->left=r; 41 if(r!=NULL) r->fa=f; 42 } 43 if(f->right==now){ 44 now->left=f; 45 f->right=l; 46 if(l!=NULL) l->fa=f; 47 } 48 f->fa=now; 49 if(now->fa==NULL) root=now; 50 return; 51 } 52 void splay(Node *now,Node *des){ 53 if(now==des) return; 54 Node *f,*gf; 55 while(now->fa!=des){ 56 f=now->fa; 57 gf=f->fa; 58 if(gf==des) rotate(now); 59 else if(gf->left==f&&f->right==now){ 60 rotate(now); 61 rotate(now); 62 } 63 else if(gf->right==f&&f->left==now){ 64 rotate(now); 65 rotate(now); 66 } 67 else if(gf->left==f&&f->left==now){ 68 rotate(f); 69 rotate(now); 70 } 71 else if(gf->right==f&&f->right==now){ 72 rotate(f); 73 rotate(now); 74 } 75 } 76 if(now->fa==NULL) root=now; 77 return; 78 } 79 Node* node_new(int vl,bool typ){ 80 node_num++; 81 node[node_num].val=vl; 82 node[node_num].type=typ; 83 node[node_num].left=NULL; 84 node[node_num].right=NULL; 85 node[node_num].fa=NULL; 86 return &node[node_num]; 87 } 88 void node_insert(Node *now,Node *v){ 89 if(root==NULL){ 90 root=v; 91 tree_type=v->type; 92 return; 93 } 94 if(now==NULL){ 95 *now=*v; 96 return; 97 } 98 if(v->val<=now->val){ 99 if(now->left==NULL){ 100 now->left=v; 101 v->fa=now; 102 } 103 else node_insert(now->left,v); 104 } 105 if(v->val>now->val){ 106 if(now->right==NULL){ 107 now->right=v; 108 v->fa=now; 109 } 110 else node_insert(now->right,v); 111 } 112 splay(v,NULL); 113 return; 114 } 115 Node* root_prev(){ 116 Node *t; 117 if(root->left!=NULL){ 118 t=root->left; 119 while(t->right!=NULL) t=t->right; 120 return t; 121 } 122 else return NULL; 123 } 124 Node* root_subs(){ 125 Node *t; 126 if(root->right!=NULL){ 127 t=root->right; 128 while(t->left!=NULL) t=t->left; 129 return t; 130 } 131 else return NULL; 132 } 133 void node_delete(Node *now){ 134 splay(now,NULL); 135 root=now; 136 if(now->left==NULL&&now->right==NULL){ 137 root=NULL; 138 return; 139 } 140 if(now->left==NULL){ 141 root=now->right; 142 root->fa=NULL; 143 return; 144 } 145 if(now->right==NULL){ 146 root=now->left; 147 root->fa=NULL; 148 return; 149 } 150 Node *l,*r; 151 l=now->left; 152 r=now->right; 153 l->fa=NULL; 154 Node *t=now->left; 155 while(t->right!=NULL) t=t->right; 156 splay(t,NULL); 157 t->right=r; 158 r->fa=t; 159 root=t; 160 return; 161 } 162 void ques(Node *now){ 163 node_insert(root,now); 164 if(now->type==tree_type) return; 165 else{ 166 splay(now,NULL); 167 Node *p,*s,*a; 168 p=root_prev(); 169 s=root_subs(); 170 a=p; 171 int t1,t2; 172 if(p!=NULL) t1=abs(p->val,now->val); 173 else t1=1<<30; 174 if(s!=NULL) t2=abs(s->val,now->val); 175 else t2=1<<30; 176 if(t2<t1){ 177 a=s; 178 ans+=t2; 179 } 180 else ans+=t1; 181 ans%=MOD; 182 node_delete(now); 183 node_delete(a); 184 } 185 return; 186 } 187 int main(){ 188 root=NULL; 189 n=read(); 190 for(int i=0;i<n;i++){ 191 p=read(); 192 x=read(); 193 ques(node_new(x,(bool)p)); 194 } 195 printf("%d",ans); 196 return 0; 197 }
代碼

Splay模板題。

這是我學過Splay之後第一次A題(也是第一次交題),也算是證明我寫的Splay沒錯。

說一下我的做法:每次先把一個點插入,如果樹空就更新樹的類型(因為同一時刻寵物收養場只能有一類(顧客或寵物));如果點和樹類型相同就繼續,否則如下處理:

把點轉到根(主要是找前驅後繼時不用考慮父親了,因為他根本沒有),找前驅和後繼,按題目要求找答案,更新答案,刪掉這個節點,再刪掉前驅或後繼。

Splay基本操作不說了。不過這次T了兩次,原來是插入後也要Splay一下,避免被卡...改過就A了。

順便開始的時候MOD還打錯了...智商不在線...

同機房大神說如果點樹類型不一樣不用插入,直接找前趨後繼,但是我蒟蒻實在沒什麽腦力想明白如何找,於是就用了以上暴力方法...

不過最終A了還是很開心的。

PS:

順便我還想說一點東西:
我用指針寫的,同機房其他人貌似都用數組實現的,據說那樣更快。不過我看洛谷上時間和別人沒啥差距,大約差距不那麽明顯。
希望以後不會被卡...

洛谷P2286寵物收養場