[HNOI2004]宠物收养所

Description

最近,阿Q开了一间宠物收养所。收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物。 每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整 数,a<2^31),而他也给每个处在收养所的宠物一个特点值。这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生: 被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少。 1. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值为a,那么它将会领养一只目前未被领养的宠物中特点值最接近a的一只宠物。 (任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的)如果有两只满足要求的宠物,即存在两只宠物他们的特点 值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物。 2. 收养宠物的人过多,假若到来一只被收养的宠物,那么哪个领养者能够领养它呢?能够领养它的领养者,是那个希望被领养宠物的特点值最接近该宠物特点值的领养 者,如果该宠物的特点值为a,存在两个领养者他们希望领养宠物的特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将成功领养该宠物。 一个领养者领养了一个特点值为a的宠物,而它本身希望领养的宠物的特点值为b,那么这个领养者的不满意程度为abs(a-b)。 【任务描述】 你得到了一年当中,领养者和被收养宠物到来收养所的情况,希望你计算所有收养了宠物的领养者的不满意程度的总和。这一年初始时,收养所里面既没有宠物,也 没有领养者。

Input

第一行为一个正整数n,n<=80000,表示一年当中来到 收养所的宠物和领养者的总数。接下来的n行,按到来时间的先后顺序描述了一年当中来到收养所的宠物和领养者的情况。每行有两个正整数a, b,其中a=0表示宠物,a=1表示领养者,b表示宠物的特点值或是领养者希望领养宠物的特点值。(同一时间呆在收养所中的,要么全是宠物,要么全是领养 者,这些宠物和领养者的个数不会超过10000个)

Output

仅有一个正整数,表示一年当中所有收养了宠物的领养者的不满意程度的总和mod 1000000以后的结果。
 
 
 
 
 
 
Splay解法+疯狂的暴力对拍
 
 
建立两棵伸展树,一棵放宠物,一棵放领养者,可知任意时刻两棵树必有一棵为空树。
删除时比较麻烦,要考虑是否存在pre和next.
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<cmath>
  6 #include<cstdlib>
  7 #include<fstream>
  8 using namespace std;
  9 //ifstream fin("fin.in");
 10 //ofstream fout("test.out");
 11 
 12 long long n,ans=0;
 13 typedef struct{
 14     int tot,root,key[100000],pre[100000],ch[100000][2];
 15     }Node;
 16 Node N[2];
 17 
 18 void Newnode(int k,int &num,int father,int d){
 19     num=++N[k].tot;N[k].key[num]=d;N[k].pre[num]=father;
 20     N[k].ch[num][0]=N[k].ch[num][1]=0;return ;
 21     }
 22 
 23 void Rotate(int k,int x,int kind){
 24     int y=N[k].pre[x];
 25     N[k].ch[y][!kind]=N[k].ch[x][kind];
 26     N[k].pre[N[k].ch[y][!kind]]=y;
 27     
 28     if(N[k].pre[y]) N[k].ch[N[k].pre[y]][y==N[k].ch[N[k].pre[y]][1]]=x;
 29     N[k].pre[x]=N[k].pre[y];
 30     
 31     
 32     N[k].pre[y]=x;
 33     N[k].ch[x][kind]=y;
 34     
 35     return ;
 36     }
 37 
 38 void Splay(int k,int x,int goal){
 39     while(N[k].pre[x]!=goal)
 40     {
 41         int y=N[k].pre[x];
 42         if(N[k].pre[y]==goal) Rotate(k,x,N[k].ch[y][0]==x);
 43         else 
 44         {
 45             int z=N[k].pre[y];int kind=N[k].ch[z][0]==y;
 46             if(N[k].ch[y][!kind]==x) {Rotate(k,y,kind);Rotate(k,x,kind);}
 47             else {Rotate(k,x,!kind);Rotate(k,x,kind);}
 48             }
 49         }
 50     N[k].root=x;return ;
 51     
 52     }
 53 
 54 int Insert(int k,int d){//return 1 则找到相等于d的节点 
 55     if(N[k].root==0) {Newnode(k,N[k].root,0,d);return 0;}//
 56     int x=N[k].root;
 57     while(N[k].ch[x][N[k].key[x]<d])
 58     {
 59         if(N[k].key[x]==d) {Splay(k,x,0);return 1;}
 60         x=N[k].ch[x][N[k].key[x]<d];
 61         }
 62     if(N[k].key[x]==d) {Splay(k,x,0);return 1;}
 63     
 64     Newnode(k,N[k].ch[x][N[k].key[x]<d],x,d);
 65     Splay(k,N[k].ch[x][N[k].key[x]<d],0);
 66     return 0;
 67     }
 68 
 69 int Pre(int k,int root){
 70     if(N[k].ch[root][0]==0) return 0;
 71     int x=N[k].ch[root][0];
 72     while(N[k].ch[x][1])
 73     x=N[k].ch[x][1];
 74     return x;
 75     }
 76 
 77 int Next(int k,int root){
 78     if(N[k].ch[root][1]==0) return 0;
 79     int x=N[k].ch[root][1];
 80     while(N[k].ch[x][0])
 81     x=N[k].ch[x][0];
 82     return x;
 83     }
 84 
 85 
 86 int a,b;
 87 void Change(int k,int c){             //删除root,splay c 
 88     int y=N[k].ch[N[k].root][1];
 89     N[k].ch[a][1]=y;
 90     N[k].pre[y]=a;
 91                 
 92     N[k].root=N[k].ch[N[k].root][0];
 93     N[k].pre[N[k].root]=0;
 94     
 95     Splay(k,c,0);
 96     }
 97 int Union(int k,int d){//合并root的两子树,并求值 
 98     a=Pre(k,N[k].root);
 99     b=Next(k,N[k].root);
100     
101     //cout<<N[k]
102     
103   //  cout<<"pre  "<<N[k].key[a]<<endl;
104    // cout<<"next  "<<N[k].key[b]<<endl;
105     if(a==0) 
106     {
107         ans+=abs(N[k].key[b]-d);ans%=1000000;
108     //    N[k].ch[N[k].pre[b]][N[k].key[N[k].pre[b]]<N[k].key[b]]=0;
109         N[k].root=N[k].ch[N[k].root][1];
110         N[k].pre[N[k].root]=0;
111         Splay(k,b,0);
112         N[k].root=N[k].ch[N[k].root][1];
113         N[k].pre[N[k].root]=0;
114         return 0;
115         }
116     else if(b==0)
117     {
118         ans+=abs(N[k].key[a]-d);ans%=1000000;
119         //N[k].ch[N[k].pre[a]][N[k].key[N[k].pre[a]]<N[k].key[a]]=0;
120         N[k].root=N[k].ch[N[k].root][0];
121         N[k].pre[N[k].root]=0;
122         Splay(k,a,0);
123         N[k].root=N[k].ch[N[k].root][0];
124         N[k].pre[N[k].root]=0;
125         return 0;
126         } 
127     else
128     {
129         ans+=min(abs(N[k].key[a]-d),abs(N[k].key[b]-d));ans%=1000000;
130         if((abs(N[k].key[a]-d)==abs(N[k].key[b]-d)&&N[k].key[a]<N[k].key[b])||abs(N[k].key[a]-d)<abs(N[k].key[b]-d))
131         {Change(k,a);return 1;}///splay a,删除a 
132         else {Change(k,b);return 1;}
133             } 
134     }
135 
136 void Print(int k,int x){
137     cout<<N[k].key[x]<<"   "<<N[k].key[N[k].pre[x]]<<endl;
138     if(N[k].ch[x][0]) Print(k,N[k].ch[x][0]);
139     if(N[k].ch[x][1]) Print(k,N[k].ch[x][1]);
140     }
141 
142 void Delete(int k,int d){
143     if(Insert(k,d))
144     {
145         a=Pre(k,N[k].root);
146         if(a==0) 
147         {
148             N[k].root=N[k].ch[N[k].root][1];
149             N[k].pre[N[k].root]=0;
150             }
151         else 
152             Change(k,a);
153         
154         return ;
155         }
156     
157 //    cout<<"k  "<<k<<"   "<<d<<endl;
158 //    Print(k,N[k].root);
159 //    
160     if(Union(k,d)) 
161     {
162         a=Pre(k,N[k].root);
163         if(a==0) 
164         {
165             N[k].root=N[k].ch[N[k].root][1];
166             N[k].pre[N[k].root]=0;
167             }
168         else 
169             Change(k,a);
170         }
171 //cout<<ans<<"  ans"<<endl;
172     } 
173 
174 int main()
175 {
176     cin>>n;
177     N[0].tot=N[1].tot=N[0].root=N[1].root=0;
178     
179     for(int i=1;i<=n;++i)
180     {
181         int x,y;
182         cin>>x>>y;
183         
184         if(x==0) {if(N[1].root==0) Insert(0,y);else Delete(1,y);}
185         if(x==1) {if(N[0].root==0) Insert(1,y);else {Delete(0,y);}}//Print(0,N[0].root);
186 //    cout<<N[0].root<<"  "<<N[1].root<<endl;  
187     //    cout<<ans<<endl;                                         
188         }
189     
190     cout<<ans<<endl;
191 //    system("pause");
192     return 0;
193     
194     } 
原文地址:https://www.cnblogs.com/noip/p/3118036.html