洛谷P2286宠物收养场
Posted Halifuda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P2286宠物收养场相关的知识,希望对你有一定的参考价值。
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宠物收养场的主要内容,如果未能解决你的问题,请参考以下文章