zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    【数据结构】堆栈
    【数据结构】线性表
    【算法】最大子列和问题
    【算法】复杂度的渐近表示
    【算法】什么是好的算法
    【算法】什么是算法
    【数据结构】什么是数据结构
    MySQL数据备份脚本
    二进制安装MySQL-5.7.28
    搭建zabbix+grafana监控
  • 原文地址:https://www.cnblogs.com/sxprovence/p/4713611.html
Copyright © 2011-2022 走看看