HNOI2004 宠物收养所 解题报告

  首先读完这题第一印象,是个裸题,很高兴。其次在打完代码之后,第二印象,很恶心,Treap的代码太长了,我今天下午敲了三遍,手都麻了。

  废话不多说,正题。其实这个题不难,有几个点是很好的,首先,他的a值没有重复的,这就保证了你找前驱和后继的正确性,再次,没有宠物和人会同时在收养所内,那么你找的前驱和后继就不用判断是人还是动物。再次,就是AC了。

  这个题一开始全WA,是因为没有注意前驱和后继不能为0的情况,导致自己领养自己或者自己被自己领养的情况出现,改了之后AC。

  Treap的裸题,建议码一下。

  直接上代码。

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cstdlib>
  6 
  7 using namespace std;
  8 const int maxn = 100000 + 5;
  9 
 10 int N,flag,temp;
 11 int Ans,size,root;
 12 int Out = 0;
 13 int ani_cnt = 0,er_cnt = 0;
 14 int pre,bac;
 15 
 16 struct data{
 17     int l,r,w,v,size,rnd;
 18 }tr[maxn];
 19 void update(int k){
 20     tr[k].size = tr[tr[k].l].size + tr[tr[k].r].size + tr[k].w;
 21 }
 22 void rturn(int &k){
 23     int t = tr[k].l;tr[k].l = tr[t].r;tr[t].r = k;
 24     tr[t].size = tr[k].size;update(k);k = t;
 25 }
 26 void lturn(int &k){
 27     int t = tr[k].r;tr[k].r = tr[t].l;tr[t].l = k;
 28     tr[t].size = tr[k].size;update(k);k = t;
 29 }
 30 void insert(int &k,int x){
 31     if(k == 0){
 32         size ++;k = size;
 33         tr[k].w = tr[k].size = 1;
 34         tr[k].v = x;tr[k].rnd = rand();
 35         return;
 36     }
 37     tr[k].size ++;
 38     if(tr[k].v == x){
 39         tr[k].w ++;
 40     }
 41     else if(x < tr[k].v){
 42         insert(tr[k].l,x);
 43         if(tr[tr[k].l].rnd < tr[k].rnd)
 44             rturn(k);
 45     }
 46     else {
 47         insert(tr[k].r,x);
 48         if(tr[tr[k].r].rnd < tr[k].rnd)
 49             lturn(k);
 50     }
 51 }
 52 void del(int &k,int x){
 53     if(k == 0)
 54         return;
 55     if(tr[k].v == x){
 56         if(tr[k].w > 1){
 57             tr[k].w --;tr[k].size --;
 58             return;
 59         }
 60         if(tr[k].r*tr[k].l == 0)
 61             k = tr[k].r + tr[k].l;
 62         else if(tr[tr[k].l].rnd < tr[tr[k].r].rnd)
 63             rturn(k),del(k,x);
 64         else
 65             lturn(k),del(k,x);
 66     }
 67     else if(x > tr[k].v)
 68         tr[k].size --,del(tr[k].r,x);
 69     else
 70         tr[k].size --,del(tr[k].l,x);
 71 }
 72 int query_rank(int k,int x){
 73     if(k == 0)
 74         return 0;
 75     if(x == tr[k].v)
 76         return tr[tr[k].l].size + 1;
 77     else if(x > tr[k].v)
 78         return tr[tr[k].l].size + tr[k].w + query_rank(tr[k].r,x);
 79     else  return query_rank(tr[k].l,x);
 80 }
 81 int query_num(int k,int x){
 82     if(k == 0)
 83         return 0;
 84     if(x <= tr[tr[k].l].size)
 85         return query_num(tr[k].l,x);
 86     else if(x > tr[tr[k].l].size + tr[k].w)
 87         return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w);
 88     else  return tr[k].v;
 89 }
 90 void query_pre(int k,int x){
 91     if(k == 0)
 92         return;
 93     if(x > tr[k].v){
 94         Ans = k;query_pre(tr[k].r,x);
 95     }
 96     else  query_pre(tr[k].l,x);
 97 }
 98 void query_sub(int k,int x){
 99     if(k == 0)
100         return;
101     if(x < tr[k].v){
102         Ans = k;query_sub(tr[k].l,x);
103     }
104     else  query_sub(tr[k].r,x);
105 }
106 
107 int main(){
108     freopen("pet.in","r",stdin);
109     freopen("pet.out","w",stdout);
110     scanf("%d",&N);
111     for(int i = 1;i <= N;++ i){
112         scanf("%d%d",&flag,&temp);
113         if(!flag){
114             insert(root,temp);
115             ani_cnt ++;
116             if(er_cnt >= ani_cnt){//如果人多动物少,那么这个动物立刻被领养  
117                 query_pre(root,temp);pre = tr[Ans].v;Ans = 0;
118                 query_sub(root,temp);bac = tr[Ans].v;Ans = 0;
119                 if(pre == bac){
120                     Out += abs(pre-temp);
121                     del(root,pre);del(root,temp);    
122                 }
123                 else{
124                     if(temp-pre < bac-temp){
125                         if(pre){
126                             Out += temp-pre;
127                             del(root,pre);del(root,temp);
128                         }
129                         else{
130                             Out += bac-temp;
131                             del(root,bac);del(root,temp);
132                         }
133                         
134                     }
135                     else{
136                         if(bac){
137                             Out += bac-temp;
138                             del(root,bac);del(root,temp);
139                         }
140                         else{
141                             Out += temp-pre;
142                             del(root,pre);del(root,temp);
143                         }
144                     }
145                 }
146                 --er_cnt;--ani_cnt;
147             }
148         }
149         else{
150             insert(root,temp);
151             er_cnt ++;
152             if(ani_cnt >= er_cnt){//如果动物多人少,那么这个人立刻领养一个动物 
153                 query_pre(root,temp);pre = tr[Ans].v;Ans = 0;
154                 query_sub(root,temp);bac = tr[Ans].v;Ans = 0;
155                 if(pre == bac){
156                     Out += abs(pre-temp);
157                     del(root,pre);del(root,temp);
158                 }
159                 else{
160                     if(temp-pre < bac-temp){
161                         if(pre){
162                             Out += temp-pre;
163                             del(root,pre);del(root,temp);
164                         }
165                         else{
166                             Out += bac-temp;
167                             del(root,bac);del(root,temp);
168                         }
169                     }
170                     else{
171                         if(bac){
172                             Out += bac-temp;
173                             del(root,bac);del(root,temp);
174                         }
175                         else{
176                             Out += temp-pre;
177                             del(root,pre);del(root,temp);
178                         }
179                     }
180                 }
181                 --er_cnt;--ani_cnt;
182             }
183         }
184         Out %= 1000000;
185     }    
186     printf("%d",Out%1000000);
187     fclose(stdin);fclose(stdout);
188     return 0;
189 }
View Code

 

posted @ 2015-08-08 18:00  漫步者。!~  阅读(305)  评论(0编辑  收藏  举报