spaly-洛谷P2286 [HNOI2004]宠物收养场
来源:互联网 发布:ubuntu 设置ip地址 编辑:程序博客网 时间:2024/04/29 09:02
https://www.luogu.org/problem/show?pid=2286#sub
我很高兴啊,我没做多久就做出来了,当然也没调多久;
虽然一开始del哪里出了写问题,但是做了这两道题,spaly的基本操作,我差不多掌握了;
对于前驱后继,我又掌握了一遍;
不多说了;
我代码里其实不用维护节点个数的;
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;struct SP{ int l,r,s,v,fa;}sp[80001];int n,m,x,y,z,rt,nn,xx,yy,mo=1e6;int animal,human;long long ans;void up(int x){sp[x].s=sp[sp[x].l].s+sp[sp[x].r].s+1;}void zig(int x){ int y=sp[x].r; if(rt==x)rt=y;else if(sp[sp[x].fa].l==x)sp[sp[x].fa].l=y;else sp[sp[x].fa].r=y; sp[y].fa=sp[x].fa; sp[x].r=sp[y].l; sp[sp[y].l].fa=x; sp[y].l=x; sp[x].fa=y; sp[y].s=sp[x].s; up(x); }void zag(int x){ int y=sp[x].l; if(rt==x)rt=y;else if(sp[sp[x].fa].l==x)sp[sp[x].fa].l=y;else sp[sp[x].fa].r=y; sp[y].fa=sp[x].fa; sp[x].l=sp[y].r; sp[sp[y].r].fa=x; sp[y].r=x; sp[x].fa=y; sp[y].s=sp[x].s; up(x); }void splay(int x,int k){ while(sp[x].fa!=k){ int y=sp[x].fa,z=sp[y].fa; if(z!=k) if((sp[z].l==y)^(sp[y].l==x)) if(sp[y].l==x)zag(y);else zig(y);else if(sp[z].l==y)zag(z);else zig(z); y=sp[x].fa; if(sp[y].l==x)zag(y);else zig(y); }}void insert(int x){ if(!rt){sp[++nn].v=x;sp[nn].s=1;rt=nn;return;} int k=rt,kk; while(k){ kk=k;sp[k].s++; if(x>sp[k].v)k=sp[k].r;else k=sp[k].l; } sp[++nn].v=x; sp[nn].s=1; sp[nn].fa=kk; if(x>sp[kk].v)sp[kk].r=nn;else sp[kk].l=nn; splay(nn,sp[rt].fa);}int qian(int k,int x){ if(!k)return -1; if(sp[k].v<x){ int y=qian(sp[k].r,x); if(y==-1)return k; return y; } if(sp[k].v>=x)return qian(sp[k].l,x);}int hou(int k,int x){ if(!k)return -1; if(sp[k].v>x){ int y=hou(sp[k].l,x); if(y==-1)return k; return y; } if(sp[k].v<=x)return hou(sp[k].r,x);}void del(int x){ int xx=qian(rt,sp[x].v),yy=hou(rt,sp[x].v); if(xx==-1&&yy==-1)rt=0;else if(xx==-1){ splay(yy,sp[rt].fa); sp[rt].s--; sp[rt].l=0; }else if(yy==-1){ splay(xx,sp[rt].fa); sp[rt].s--; sp[rt].r=0; }else{ splay(xx,sp[rt].fa); splay(yy,rt); sp[rt].s--; sp[sp[rt].r].s--; sp[sp[rt].r].l=0; }}int find(int k,int x){ if(!k)return 0; if(sp[k].v==x)return k; if(sp[k].v<x)return find(sp[k].r,x); return find(sp[k].l,x); }int main(){ scanf("%d",&m); while(m--){ scanf("%d%d",&y,&x); if(y) if(!animal){ insert(x); human++; }else{ animal--; int f=find(rt,x); if(f){del(f);continue;} xx=qian(rt,x); yy=hou(rt,x); if(yy==-1){ans+=x-sp[xx].v;del(xx);}else if(xx==-1){ans+=sp[yy].v-x;del(yy);}else if(x-sp[xx].v<=sp[yy].v-x) {ans+=x-sp[xx].v;del(xx);}else {ans+=sp[yy].v-x;del(yy);} } else if(!human){ insert(x); animal++; }else{ human--; int f=find(rt,x); if(f){del(f);continue;} xx=qian(rt,x); yy=hou(rt,x); if(yy==-1){ans+=x-sp[xx].v;del(xx);}else if(xx==-1){ans+=sp[yy].v-x;del(yy);}else if(x-sp[xx].v<=sp[yy].v-x) {ans+=x-sp[xx].v;del(xx);}else {ans+=sp[yy].v-x;del(yy);} } ans%=mo; } printf("%d",ans);}
议论:关于spaly的del;
这个是标准del;
void del(int x){ int xx=qian(rt,sp[x].v),yy=hou(rt,sp[x].v); if(xx==-1&&yy==-1)rt=0;else if(xx==-1){ splay(yy,sp[rt].fa); sp[rt].s--; sp[rt].l=0; }else if(yy==-1){ splay(xx,sp[rt].fa); sp[rt].s--; sp[rt].r=0; }else{ splay(xx,sp[rt].fa); splay(yy,rt); sp[rt].s--; sp[sp[rt].r].s--; sp[sp[rt].r].l=0; }}
就是把x的前驱后继找出来搞,我们可以在整个区间前后加一个空节点,那我们就不用特判找不到前驱的情况了;
但我有怎么一个想法;
我们假如要删除x节点,我们不断通过旋转,把x旋转到底层,就直接把x删掉就好了;
void del(int x){ for(int k=x;k;k=sp[k].fa)sp[k].s--; while(sp[x].l&&sp[x].r){ zag(x); sp[sp[x].fa].s--; } if(x==rt)rt=sp[x].l+sp[x].r;else if(sp[sp[x].fa].r==x)sp[sp[x].fa].r=sp[x].l+sp[x].r;else sp[sp[x].fa].l=sp[x].l+sp[x].r; sp[sp[x].l+sp[x].r].fa=sp[x].fa;}
可是这样三个点死循环;
为什么?
0 0
- spaly-洛谷P2286 [HNOI2004]宠物收养场
- 洛谷P2286 [HNOI2004]宠物收养场
- 洛谷P2286 [HNOI2004]宠物收养场(BZOJ1208)
- [伸展树]洛谷P2286 宠物收养场
- [HNOI2004]宠物收养场
- [HNOI2004]宠物收养场 Treap
- [HNOI2004]宠物收养场 set简单应用
- [HNOI2004]宠物收养所
- HNOI2004宠物收养所
- HNOI2004-宠物收养所
- 【HNOI2004】宠物收养所
- [HNOI2004]宠物收养所
- HNOI2004 宠物收养所
- [HNOI2004]宠物收养所
- [HNOI2004]宠物收养所 SBT
- HNOI2004 宠物收养所 SBT
- 【HNOI2004】【SBT】宠物收养所
- [bzoj1208] [HNOI2004]宠物收养所
- mysql差异备份——增量备份区别
- Shell常用命令整理
- 12BET Malaysia 30% Birthday Bonus
- 蓝桥杯
- Linux系统下安装rz/sz命令及使用说明
- spaly-洛谷P2286 [HNOI2004]宠物收养场
- AngularJS中的依赖注入 二
- Oracle视图查询慢之统计信息收集
- 选择父子下的所有孩子元素,同时移除
- 性能优化------内存优化1
- JSON优点简单总结
- iOS返璞归真,译文系列——UIView
- Android 基础篇之环境配置
- Linux下的文本dos格式转Unix格式,去除^M符号