bzoj 1208 宠物收养所

题目大意:

有一家宠物收养所,有没有被收养的宠物或者是想收养宠物的人,每个宠物有一个个性值,每个想收养宠物的人有一个理想的个性值

每一个时刻,宠物收养所里只能有想收养宠物的人或宠物

当人领走宠物时,就会有一个不满意度  这个领养者的不满意程度为abs(a-b) 若存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物

使每个人不满意度尽可能小

求这个总的不满意度

思路:

用一棵splay维护当前收养所里的东西

记一个标记表示收养所里是人还是宠物

如果插入的点和收养所的标记不一样,就删掉那个满足题意的点

如果一样,就插入并将它splay到根节点

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstdlib>
  6 #include<cstring>
  7 #include<queue>
  8 #include<map>
  9 #include<vector>
 10 #define ll long long
 11 #define inf 2147483611
 12 #define MAXN 80101
 13 #define MOD 1000000
 14 using namespace std;
 15 inline int read()
 16 {
 17     int x=0,f=1;char ch=getchar();
 18     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 20     return x*f;
 21 }
 22 int ls[MAXN],rs[MAXN],val[MAXN],fa[MAXN],ans,rt,cnt,n,pre,sub,valpre,valsub;
 23 bool flag;
 24 void L_rotate(int x)
 25 {
 26     int y=fa[x],z=fa[y];
 27     rs[y]=ls[x];
 28     if(ls[x]!=-1) fa[ls[x]]=y; 
 29     fa[x]=z;
 30     if(z!=-1) {if(ls[z]==y) ls[z]=x;else rs[z]=x;}
 31     ls[x]=y,fa[y]=x;
 32 }
 33 void R_rotate(int x)
 34 {
 35     int y=fa[x],z=fa[y];
 36     ls[y]=rs[x];
 37     if(rs[x]!=-1) fa[rs[x]]=y; 
 38     fa[x]=z;
 39     if(z!=-1) {if(ls[z]==y) ls[z]=x;else rs[z]=x;}
 40     rs[x]=y,fa[y]=x;
 41 }
 42 void splay(int x)
 43 {
 44     int y,z;
 45     while(fa[x]!=-1)
 46     {
 47         y=fa[x],z=fa[y];
 48         if(z==-1) {if(ls[y]==x) R_rotate(x);else L_rotate(x);}
 49         else
 50         {
 51             if(ls[y]==x&&ls[z]==y) {R_rotate(y);R_rotate(x);}
 52             if(rs[y]==x&&rs[z]==y) {L_rotate(y);L_rotate(x);}
 53             if(ls[y]==x&&rs[z]==y) {R_rotate(x);L_rotate(x);}
 54             if(rs[y]==x&&ls[z]==y) {L_rotate(x);R_rotate(x);}
 55         }
 56     }
 57     rt=x;
 58 }
 59 void Insert(int x,int pos)
 60 {
 61     if(x>val[pos])
 62     {
 63         if(rs[pos]==-1) rs[pos]=cnt,fa[cnt]=pos,ls[cnt]=rs[cnt]=-1,val[cnt]=x;
 64         else Insert(x,rs[pos]);
 65     }
 66     if(x<=val[pos])
 67     {
 68         if(ls[pos]==-1) ls[pos]=cnt,fa[cnt]=pos,ls[cnt]=rs[cnt]=-1,val[cnt]=x;
 69         else Insert(x,ls[pos]);
 70     }
 71 }
 72 void find_pre(int x)
 73 {
 74     int pos=rt;
 75     pre=-1,valpre=inf;
 76     while(pos!=-1)
 77     {
 78         if(val[pos]<x&&x-val[pos]<valpre) pre=pos,valpre=x-val[pos];
 79         if(val[pos]<x) pos=rs[pos];
 80         else pos=ls[pos];
 81     }
 82 }
 83 void find_sub(int x)
 84 {
 85     int pos=rt;
 86     sub=-1,valsub=inf;
 87     while(pos!=-1)
 88     {
 89         if(val[pos]>x&&val[pos]-x<valsub) sub=pos,valsub=val[pos]-x;
 90         if(val[pos]<x) pos=rs[pos];
 91         else pos=ls[pos];
 92     }
 93 }
 94 void dlt(int x)
 95 {
 96     splay(x);
 97     if(ls[x]==-1&&rs[x]==-1) {rt=-1;return ;}
 98     if(ls[x]==-1) {rt=rs[x];fa[rs[x]]=-1;return ;}
 99     if(rs[x]==-1) {rt=ls[x];fa[ls[x]]=-1;return ;}
100     int k=ls[x];while(rs[k]!=-1) k=rs[k];fa[ls[x]]=-1;
101     splay(k);rs[k]=rs[x],fa[rs[x]]=k,rt=k;
102 }
103 void insert(bool a,int x)
104 {
105     cnt++;
106     int tmp=inf;
107     if(rt==-1) {flag=a,fa[cnt]=ls[cnt]=rs[cnt]=-1,val[cnt]=x,rt=cnt;return ;}
108     if(a==flag) {Insert(x,rt);splay(cnt);}
109     else
110     {
111         find_pre(x);find_sub(x);
112         if(pre!=-1||sub!=-1)
113         {
114             int tmp=inf+1,num=0;
115             if(pre!=-1&&valpre<tmp) tmp=valpre,num=pre;
116             if(sub!=-1&&valsub<tmp) tmp=valsub,num=sub;
117             (ans+=tmp)%=MOD;dlt(num);
118         }  
119     }
120 }
121 int main()
122 {
123     n=read();
124     bool a;int b;
125     flag=read(),rt=read(),cnt++,fa[cnt]=ls[cnt]=rs[cnt]=-1,val[cnt]=rt,rt=cnt;
126     for(int i=1;i<n;i++)
127     {
128         a=read(),b=read();
129         insert(a,b);
130     }
131     printf("%d",ans);
132 }
View Code

 

posted @ 2017-11-24 16:40  jack_yyc  阅读(210)  评论(0编辑  收藏  举报