bzoj 1208 宠物收养所
题目大意:
有一家宠物收养所,有没有被收养的宠物或者是想收养宠物的人,每个宠物有一个个性值,每个想收养宠物的人有一个理想的个性值
每一个时刻,宠物收养所里只能有想收养宠物的人或宠物
当人领走宠物时,就会有一个不满意度 这个领养者的不满意程度为abs(a-b) 若存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物
使每个人不满意度尽可能小
求这个总的不满意度
思路:
用一棵splay维护当前收养所里的东西
记一个标记表示收养所里是人还是宠物
如果插入的点和收养所的标记不一样,就删掉那个满足题意的点
如果一样,就插入并将它splay到根节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }