您的位置:首页 > 产品设计 > UI/UE

POJ 3481 Double Queue【SBT】

2012-09-27 23:50 393 查看
http://poj.org/problem?id=3481

该SBT模板只实现了一些简单的操作,我会不断完善其它功能。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

const int maxn = 100010;

struct Node {
int key, val;
Node(){};
Node(int a, int b) {
key = a; val = b;
}
bool operator < (Node b) {
return val < b.val;
}
bool operator > (Node b) {
return val > b.val;
}
bool operator == (Node b) {
return val == b.val;
}
bool operator >= (Node b) {
return val >= b.val;
}
Node operator + (int a) {
return Node(key, val + a);
}
};

template<typename Type>
class SBT
{
public:
SBT() { Clear(); }
void Clear() {
tot = 0, root = 0;
lch[0] = rch[0] = sz[0] = 0;
}
int Size() { return sz[root]; }
bool Empty() { return 0 == sz[root]; }
bool Find(Type k) { return Find(root, k); }
void InsertR(Type k) { Insert(root, k); }
void Insert(Type k) { if (!Find(k)) InsertR(k); }
void Delete(Type k) { Delete(root, k); }
int GetRank(Type k) { return GetRank(root, k); }
Type GetKth(int k) { return GetKth(root, k); }
Type GetMin() { return GetKth(root, 1); }
Type GetMax() { return GetKth(root, Size()); }

private:
void LeftRotate(int &t) {
int k = rch[t];
rch[t] = lch[k];
lch[k] = t;
sz[k] = sz[t];
sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
t = k;
}
void RightRotate(int &t) {
int k = lch[t];
lch[t] = rch[k];
rch[k] = t;
sz[k] = sz[t];
sz[t] = 1 + sz[lch[t]] + sz[rch[t]];
t = k;
}
void Maintain(int &t, bool flag) {
if (0 == t) return ;
if (false == flag) {
if (sz[lch[lch[t]]] > sz[rch[t]]) {
RightRotate(t);
} else if (sz[rch[lch[t]]] > sz[rch[t]]) {
LeftRotate(lch[t]);
RightRotate(t);
} else {
return ;
}
} else {
if (sz[rch[rch[t]]] > sz[lch[t]]) {
LeftRotate(t);
} else if (sz[lch[rch[t]]] > sz[lch[t]]) {
RightRotate(rch[t]);
LeftRotate(t);
} else {
return ;
}
}
Maintain(lch[t], false);
Maintain(rch[t], true);
Maintain(t, false);
Maintain(t, true);
}
Type GetKth(int t, int k) {
if (sz[lch[t]] >= k)
return GetKth(lch[t], k);
if (sz[lch[t]] == k - 1)
return key[t];
return GetKth(rch[t], k - sz[lch[t]] - 1);
}
int GetRank(int t, Type k) {
if (0 == t) return 1; // 查找不存在的元素的rank,可以得到小于该元素的元素的个数
if (k < key[t]) return GetRank(lch[t], k);
if (k > key[t]) return sz[lch[t]] + 1 + GetRank(rch[t], k);
return sz[lch[t]] + 1;
}
bool Find(int t, Type k) {
if (0 == t) {
return false;
} else if (k < key[t]) {
return Find(lch[t], k);
} else {
return (key[t] == k || Find(rch[t], k));
}
}
void Insert(int &t, Type k) {
if (t == 0) {
t = ++tot;
lch[t] = rch[t] = 0;
sz[t]= 1;
key[t] = k;
return ;
}
sz[t]++;
if (k < key[t]) {
Insert(lch[t], k);
} else {
Insert(rch[t], k);
}
Maintain(t, k >= key[t]);
}
Type Delete(int &t, Type k) {
sz[t]--;
if ((key[t] == k) || (k < key[t] && lch[t] == 0) || (k > key[t] && rch[t] == 0)) {
Type tmp = key[t];
if (0 == lch[t] || 0 == rch[t]) {
t = lch[t] + rch[t];
} else {
key[t] = Delete(lch[t], key[t] + 1);
}
return tmp;
} else {
if (k < key[t]) {
return Delete(lch[t], k);
} else {
return Delete(rch[t], k);
}
}
}

private:
int sz[maxn];
Type key[maxn];
int lch[maxn];
int rch[maxn];
int root, tot;
};

SBT<Node> sbt;

int main()
{
int op, a, b;
sbt.Clear();
while (scanf("%d", &op)) {
if (0 == op) break;
if (1 == op) {
scanf("%d%d", &a, &b);
sbt.Insert(Node(a, b));
} else if (2 == op) {
if (sbt.Empty()) {
printf("0\n");
} else {
Node tmp = sbt.GetMax();
printf("%d\n", tmp.key);
sbt.Delete(tmp);
}
} else {
if (sbt.Empty()) {
printf("0\n");
} else {
Node tmp = sbt.GetMin();
printf("%d\n", tmp.key);
sbt.Delete(tmp);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: