【codevs1285】【BZOJ1208】宠物收养所,splay练习
2016-03-11 20:15
363 查看
传送门1
传送门2
写在前面:我自己也会被写进机房大事记……
思路:很裸的splay练习,只涉及查前驱后继和删除操作,加一个标记记录现在是宠物多还是人多即可
注意:
1.查询和调用前驱后继时可能两者同时存在,记得判断一下
2.不知道为什么用bool型做树的标记时总是自己莫名改值,害我调了好久
代码:
传送门2
写在前面:我自己也会被写进机房大事记……
思路:很裸的splay练习,只涉及查前驱后继和删除操作,加一个标记记录现在是宠物多还是人多即可
注意:
1.查询和调用前驱后继时可能两者同时存在,记得判断一下
2.不知道为什么用bool型做树的标记时总是自己莫名改值,害我调了好久
代码:
#include<bits/stdc++.h> #define mod 1000000 int n,x,tot,root,ans; int hand,flag; struct os { int data,fa,left,right,sz; }a[100010]; int in() { int f=1,t=0; char ch=getchar(); while (ch>'9'||ch<'0') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9') t=t*10+ch-'0',ch=getchar(); return f*t; } void made(int x) { a[++tot].data=x; a[tot].sz=1; } void ct(int now) { a[now].sz=a[now].left+a[now].right+1; } void rorate(int now,bool flag) { int pa=a[now].fa; if (flag) { a[pa].left=a[now].right; if (a[now].right)a[a[now].right].fa=pa; if (a[pa].fa) { if (a[a[pa].fa].left==pa) a[a[pa].fa].left=now; else a[a[pa].fa].right=now; } a[now].fa=a[pa].fa; a[pa].fa=now; a[now].right=pa; } else { a[pa].right=a[now].left; if (a[now].left)a[a[now].left].fa=pa; if (a[pa].fa) { if (a[a[pa].fa].left==pa) a[a[pa].fa].left=now; else a[a[pa].fa].right=now; } a[now].fa=a[pa].fa; a[pa].fa=now; a[now].left=pa; } ct(pa); ct(now); } void splay(int x,int goal) { int y; while (a[x].fa!=goal) { y=a[x].fa; if (a[y].fa==goal) { if (a[y].left==x) rorate(x,1); else rorate(x,0); } else if (y==a[a[y].fa].left) { if (a[y].left==x) rorate(y,1); else rorate(x,0); rorate(x,1); } else { if (a[y].right==x) rorate(y,0); else rorate(x,1); rorate(x,0); } } if (!goal) root=x; } void insert(int x) { made(x);a[tot].data=x; if (!root) {root=tot;return;} int now=root; while (now) { if (x<a[now].data) { if (!a[now].left) {a[now].left=tot;a[tot].fa=now;break;} else now=a[now].left; } else { if (!a[now].right) {a[now].right=tot;a[tot].fa=now;break;} else now=a[now].right; } } splay(tot,0); } int find(int x) { int now=root; while (now) { if (a[now].data==x) return now; else if (a[now].data>x) now=a[now].left; else now=a[now].right; } return 0; } int find_max(int now) { if (!now) return 0; while (now) { if (a[now].right) now=a[now].right; else return now; } } bool del(int now) { splay(now,0); if (!a[now].left&&!a[now].right){root=0;return 1;} else if (!a[now].left) { a[a[now].right].fa=0; root=a[now].right; } else if (!a[now].right) { a[a[now].left].fa=0; root=a[now].left; } else { int child=find_max(a[now].left); splay(child,root); root=child; a[child].right=a[now].right; a[a[now].right].fa=child; a[child].fa=0; ct(child); } return 1; } int find_next_max(int x) { int now=root,k=0; while (now) { if (a[now].data>x) k=(a[k].data>a[now].data||!k)?now:k, now=a[now].left; else now=a[now].right; } if (k) splay(k,0); return k; } int find_next_min(int x) { int now=root,k=0; while (now) { if (a[now].data<x) k=(a[k].data<a[now].data||!k)?now:k, now=a[now].right; else now=a[now].left; } if (k) splay(k,0); return k; } main() { n=in(); for (int i=1;i<=n;i++) { scanf("%d%d",&hand,&x); if (!root) flag=hand; if (flag==hand) insert(x); else { int p,p1=find_next_min(x),p2=find_next_max(x); if (p1&&(x-a[p1].data<=a[p2].data-x||!p2)) p=p1; else p=p2; ans=(ans+abs(a[p].data-x))%mod; del(p); } } printf("%d",ans); }
相关文章推荐
- linux下部署项目问题
- 数据库的一些基本概念
- 顺序栈
- 第六届蓝桥杯 软件类省赛真题 第七题:加法变乘法
- 造船PDM系统介绍
- 第一次实验报告1
- linux ptrace
- 计算机网络原理大纲思维导图
- Google面试题,excel十进制字符串转换(java)
- Erlang 执行批处理文件
- post请求导致参数为空的原因
- js学习cookie封装之获取
- HDU 2817 多校联赛1
- Oracle EBS在编码方式为AL32UTF8时的注意事项
- 设计模式(9)之观察者模式
- 有关HTTPS和S-HTTP
- LinearLayout布局中Layout_weight的深刻理解-为何需设置android:layout_width="0dp"
- python中声明编码方式必须放在第一行
- CCActionTimeline详解和倒播动画
- iOS 程序打包ipa流程以及打包之后无法在真机上进行调试