bzoj1208: [HNOI2004]宠物收养所 SBT&&Splay
2014-12-12 23:18
393 查看
初次写SBT。。。。。感觉sbt跟线段树一样,多写写就熟了。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define maxn 1100000 #define mod 1000000 #define INF 1e9 int root,siz[maxn],val[maxn],ls[maxn],rs[maxn]; int cnt,people,ans,n; inline int getint() { char c; int res; while (c = getchar(), ('0' > c || c > '9') && c != '-'); int flag=1; if(c=='-') flag=-1,res=0; else res=c-'0'; while (c = getchar(), '0' <= c && c <= '9') res = res * 10 + c - '0'; return res*flag; } inline void rotate_l(int &x) { int y=rs[x]; rs[x]=ls[y]; ls[y]=x; siz[y]=siz[x]; siz[x]=siz[ls[x]]+siz[rs[x]]+1; x=y; } inline void rotate_r(int &x) { int y=ls[x]; ls[x]=rs[y]; rs[y]=x; siz[y]=siz[x]; siz[x]=siz[ls[x]]+siz[rs[x]]+1; x=y; } inline void maintain(int& x,int fg) { if(!fg) { if(siz[ls[ls[x]]]>siz[rs[x]]) rotate_r(x); else if(siz[rs[ls[x]]]>siz[rs[x]]) rotate_l(ls[x]),rotate_r(x); else return; } else { if(siz[rs[rs[x]]]>siz[ls[x]]) rotate_l(x); else if(siz[ls[rs[x]]]>siz[ls[x]]) rotate_r(rs[x]),rotate_l(x); else return; } maintain(ls[x],0); maintain(rs[x],1); maintain(x,1); maintain(x,0); } inline void insert(int& x,int b) { if(!x) { cnt++; x=cnt; ls[x]=rs[x]=0; siz[x]=1; val[x]=b; return ; } else { siz[x]++; if(b<val[x]) insert(ls[x],b); else insert(rs[x],b); maintain(x,b>=val[x]); } } inline int pred(int& x,int y,int b) { if(!x) return y; if(b>val[x]) return pred(rs[x],x,b); return pred(ls[x],y,b); } inline int succ(int& x,int y,int b) { if(!x) return y; if(b<val[x]) return succ(ls[x],x,b); return succ(rs[x],y,b); } int delt(int& x,int b) { siz[x]--; if(b==val[x]||(b>val[x]&&rs[x]==0)||(b<val[x]&&ls[x]==0)) { int y=val[x]; if(ls[x]==0||rs[x]==0) x=ls[x]+rs[x]; else val[x]=delt(ls[x],val[x]+1); return y; } else { if(b<val[x]) return delt(ls[x],b); else return delt(rs[x],b); } } int main() { int a,b; int f1,f2; scanf("%d",&n); for(int i=1;i<=n;i++) { a=getint(); b=getint(); if(siz[root]==0||a==people) { people=a; insert(root,b); continue; } f1=pred(root,0,b); f2=succ(root,0,b); if(f1!=0) f1=val[f1]; else f1=INF; if(f2!=0) f2=val[f2]; else f2=INF; if(abs(f1-b)<=abs(f2-b)) delt(root,f1),ans+=abs(f1-b)%mod; else delt(root,f2),ans+=abs(f2-b)%mod; ans%=mod; } printf("%d\n",ans); return 0; }这个题用splay竟然比SBT快。。。。96ms
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define maxn 1100000 #define mod 1000000 #define INF 1e9 int root,siz[maxn],val[maxn],tr[maxn][2],fa[maxn]; int cnt,people,ans,n,t1,t2; inline int getint() { char c; int res; while (c = getchar(), ('0' > c || c > '9') && c != '-'); int flag=1; if(c=='-') flag=-1,res=0; else res=c-'0'; while (c = getchar(), '0' <= c && c <= '9') res = res * 10 + c - '0'; return res*flag; } inline void rotateup(int x,int& rt) { int l,r,y,z; y=fa[x];z=fa[y]; if(tr[y][0]==x)l=0;else l=1;r=l^1; if(y==rt) rt=x; else { if(tr[z][0]==y) tr[z][0]=x; else tr[z][1]=x; } fa[y]=x;fa[x]=z;fa[tr[x][r]]=y; tr[y][l]=tr[x][r];tr[x][r]=y; } inline void splay(int x,int& rt) { int y,z; while(x!=rt) { y=fa[x];z=fa[y]; if(y!=rt) { if( (tr[y][0]==x)^(tr[z][0]==y) ) rotateup(x,rt); else rotateup(y,rt); } rotateup(x,rt); } } inline void insert(int& x,int last,int b) { if(!x) { cnt++; x=cnt; val[x]=b; fa[x]=last; splay(x,root); return; } if(b<val[x]) insert(tr[x][0],x,b); else insert(tr[x][1],x,b); } inline void pred(int x,int b) { if(x==0)return; if(val[x]<=b){t1=x,pred(tr[x][1],b);} else pred(tr[x][0],b); } inline void succ(int x,int b) { if(x==0)return; if(val[x]>=b){t2=x,succ(tr[x][0],b);} else succ(tr[x][1],b); } inline void delt(int x) { splay(x,root); if(tr[x][0]*tr[x][1]==0) { root=tr[x][0]+tr[x][1]; } else { int k=tr[x][1]; while(tr[k][0])k=tr[k][0]; tr[k][0]=tr[x][0];fa[tr[x][0]]=k; root=tr[x][1]; } fa[root]=0; } int main() { int a,b; int f1,f2; scanf("%d",&n); for(int i=1;i<=n;i++) { a=getint(); b=getint(); if(!root) { people=a; insert(root,0,b); continue; } else if(a==people) { insert(root,0,b); continue; } else { t1=t2=-1; pred(root,b);succ(root,b); if(t1==-1){ans+=val[t2]-b;ans%=1000000;delt(t2);} else if(t2==-1){ans+=b-val[t1];ans%=1000000;delt(t1);} else { if(b-val[t1]>val[t2]-b) {ans+=val[t2]-b;ans%=1000000;delt(t2);} else{ans+=b-val[t1];ans%=1000000;delt(t1);} } } } printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj 1208: [HNOI2004]宠物收养所 splay
- BZOJ 题目1208: [HNOI2004]宠物收养所(SBT)
- [BZOJ1208][HNOI2004]宠物收养所(平衡树splay)
- [Splay]BZOJ 1208——[HNOI2004]宠物收养所
- BZOJ-1208: [HNOI2004]宠物收养所 (splay 查询前驱后继 set也可)
- BZOJ 1208 HNOI 2004 宠物收养所 splay
- BZOJ 1208 [HNOI 2004] 宠物收养所 Splay
- BZOJ1208: [HNOI2004]宠物收养所 Splay
- BZOJ 1208: [HNOI2004]宠物收养所 set,或者splay
- 【BZOJ 1208】 [HNOI2004]宠物收养所 splay模板(指针)+set
- [bzoj1208][HNOI2004]宠物收养所——splay
- 【set】【Splay】【pb_ds】bzoj1208 [HNOI2004]宠物收养所
- 【bzoj1208】[HNOI2004]宠物收养所 Splay
- [BZOJ1208] [HNOI2004] 宠物收养所 - splay
- BZOJ 1208: [HNOI2004]宠物收养所 SBT
- [BZOJ1208][HNOI2004]宠物收养所(平衡树splay)
- BZOJ 1208 [HNOI2004] 宠物收养所 题解&代码
- bzoj 1208 [HNOI2004]宠物收养所
- bzoj 1208 [HNOI2004]宠物收养所 Splay
- _bzoj1208 [HNOI2004]宠物收养所【Splay】