poj3481 Double Queue(set模拟or splay)
来源:互联网 发布:手机指南针软件 编辑:程序博客网 时间:2024/05/16 15:01
题目链接
题目意思明确。可以用两个set来模拟,一个大的优先,一个小的优先,同时删除、同时加入。
struct item1 { int k, p; item1() {} item1(int k, int p) : k(k), p(p) {} bool operator < (const item1& rhs) const { return p < rhs.p; }};struct item2 { int k, p; item2() {} item2(int k, int p) : k(k), p(p) {} bool operator < (const item2& rhs) const { return p > rhs.p; }};set<item1> st1;set<item2> st2;int main(int argc, const char * argv[]){ int op; while(~scanf("%d", &op) && op) { if (op == 1) { int k,p; scanf("%d%d", &k, &p); st1.insert(item1(k, p)); st2.insert(item2(k, p)); }else if (op == 2) { if (st2.empty()) { printf("0\n"); continue; } item2 temp2 = *st2.begin(); st2.erase(temp2); item1 temp1(temp2.k, temp2.p); st1.erase(temp1); printf("%d\n", temp2.k); }else if (op == 3) { if (st1.empty()) { printf("0\n"); continue; } item1 temp1 = *st1.begin(); st1.erase(temp1); item2 temp2(temp1.k, temp1.p); st2.erase(temp2); printf("%d\n", temp1.k); } } return 0;}
也可以算成splay的入门题,只要保持树的中序遍历是有序的就行。
百度的图讲解很多,易懂。
#include <stdio.h>#define MAXN 100005struct TreeNode{ //键,子树大小,父节点编号,两个儿子节点编号,当前节点的附加信息 int key, size, fa, son[2], num; TreeNode() {} TreeNode(int _key, int _size, int _fa, int _num) { key = _key;size = _size;fa = _fa; num = _num;son[0] = son[1] = 0; }}T[MAXN];struct SplayTree { int rt, cnt; void init(){cnt = 1, rt = 0;} void PushUp(int x) { T[x].size = T[T[x].son[0]].size + T[T[x].son[1]].size + 1; } /*p是旋转方向,旋转后x的深度-1*/ void Rotate(int x, int p) { int y = T[x].fa; T[y].son[!p] = T[x].son[p]; T[T[x].son[p]].fa = y; T[x].fa = T[y].fa; if (T[x].fa) T[T[x].fa].son[T[T[x].fa].son[1] == y] = x; T[x].son[p] = y; T[y].fa = x; /*y under x*/ PushUp(y); PushUp(x); } /*x旋转到to下面*/ void Spaly(int x, int to) { while(T[x].fa != to) { if (T[T[x].fa].fa == to) { Rotate(x, T[T[x].fa].son[0] == x); } else { int y = T[x].fa, z = T[y].fa; int p = (T[z].son[0] == y);/*y的旋转方向*/ if (T[y].son[p] == x) Rotate(x, !p), Rotate(x, p); else Rotate(y, p), Rotate(x, p); } } /*to=0,说明x是主根*/ if (to == 0) rt = x; } /*按键查找,没找到返回0*/ int find(int key) { int x = rt; while(x && T[x].key != key) { x = T[x].son[key > T[x].key]; } if (x) Spaly(x, 0);/*如果找到,就旋转到根节点下面*/ return x; } void insert(int key, int num) { if (!rt) { T[rt = cnt++] = TreeNode(key, 1, 0, num); } else { /*y纪录的是x的父节点的编号*/ int x = rt, y = 0; while(x) { y = x; x = T[x].son[key > T[x].key]; } /*创建新的节点*/ T[x = cnt++] = TreeNode(key, 1, y, num); T[y].son[key > T[y].key] = x; Spaly(x, 0); } } void Delete(int key) { int x = find(key); if (!x) return ; /*左找最大键*/ int y = T[x].son[0]; while(T[y].son[1]) y = T[y].son[1]; /*右找最小键*/ int z = T[x].son[1]; while(T[z].son[0]) z = T[z].son[0]; if (!y && !z) { rt = 0; return ; } if (!y)/*x没有左子树*/ { Spaly(z, 0); T[z].son[0] = 0;/*x没有左子树,故son[0] = 0*/ PushUp(z); return ; } if (!z)/*x没有右子树*/ { Spaly(y, 0); T[y].son[1] = 0;/*x没有右子树,故son[1] = 0*/ PushUp(y); return ; } /*左右子树同时有,先把y移到0下面,在把z移到y下面,注意更新顺序*/ Spaly(y, 0); Spaly(z, y); T[z].son[0] = 0; PushUp(z); PushUp(y); } /*找第p大*/ int GetPth(int p) { if (!rt) return 0; int x = rt;//, ret = 0; while(x) { /*当前节点+左子树*/ if (p == T[T[x].son[0]].size + 1) { break; } if (p > T[T[x].son[0]].size + 1) { p-= T[T[x].son[0]].size + 1; x = T[x].son[1]; }else x = T[x].son[0]; } Spaly(x, 0); return x; }}solve;int nCase = 0;int main(){ // freopen("/Users/jamesqi/Desktop/in.txt","r",stdin); int p, key, num, x; solve.init(); while(scanf("%d", &p) && p) { switch(p) { case 1: /*插入键、值*/ scanf("%d%d", &num, &key); solve.insert(key, num); break; case 2: /*最大值*/ num = T[solve.rt].size; x = solve.GetPth(num); if (x) { printf("%d\n", T[x].num); solve.Delete(T[x].key); } else printf("0\n"); break; case 3: /*最小值*/ x = solve.GetPth(1); if (x) { printf("%d\n", T[x].num); solve.Delete(T[x].key); } else printf("0\n"); break; } } return 0;}
0 0
- poj3481 Double Queue(set模拟or splay)
- poj3481 Double Queue splay
- POJ3481 Double Queue (Splay)
- poj3481-Double Queue
- POJ3481 Double Queue
- poj3481 Double Queue
- poj3481 Double Queue
- poj3481——Double Queue
- 【POJ3481】Double Queue——伸展树
- poj3481(map的使用)Double Queue
- hdu 1908 Double Queue ( splay )
- poj 3481 Double Queue splay
- POJ 3481 Double Queue [splay]
- <set> Double Queue (P3481)
- Double Queue set解法
- POJ 3481 Double Queue(Splay)
- POJ 3481 Double Queue (Splay || 水题)
- Double Queue(SET水题)
- CocosStudio(二)创建UI项目
- 【git】github基础
- Swift3.0 访问通讯录
- iOS10:CallKit的简单应用
- SRS产品规划
- poj3481 Double Queue(set模拟or splay)
- 141. Linked List Cycle
- C#复制数组的两种方式,以及效率比较
- Undefined symbols for architecture i386: "_OBJC_CLASS_$_xxxxx", referenced from:
- 雾化
- Effective C++阅读笔记(二):设计与声明
- JAVA学习之创建一个小的命令行程序以及创建一个小的有对话界面的程序
- tableview 编辑状态下,UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert 多选的时候,替换圆圈图片
- 欢迎使用CSDN-markdown编辑器