洛谷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宠物收养场的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P2286宠物收养场·改

宠物收养场 Treap

[HNOI 2004]宠物收养场

[HNOI2004]宠物收养场——treap

1208. [HNOI2004]宠物收养场平衡树-splay

HNOI2004 宠物收养场 [Treap]