代码如下
#include <iostream>
#include <vector>
using namespace std;
namespace String {
class Node {
public:
int value, size, cnt;
Node* leftChild, * rightChild, * parent;
Node();
Node(int v);
Node(int v, int c);
};
Node::Node() {
value = size = cnt = 0;
leftChild = rightChild = parent = nullptr;
}
Node::Node(int v) {
value = v, size = cnt = 1;
leftChild = rightChild = parent = nullptr;
}
Node::Node(int v, int c) {
value = v, size = cnt = c;
leftChild = rightChild = parent = nullptr;
}
class ScapegoatTree {
private:
const double ALPHA = 0.75;
Node* root;
int deletedCnt;
void Update(Node* node);
bool ShouldRes(Node* node);
Node* BuildFromVec(std::vector<std::pair <int, int> > &vec, int l, int r);
void InorderTraversal(Node* node, std::vector<std::pair <int, int> > &vec);
Node* Restructure(Node* node);
Node* HiddenInsert(Node* node, int value);
Node* Check(Node* node, int value);
void Mark(Node* node, int value);
void HiddenDisplay(Node* node);
public:
ScapegoatTree();
void Insert(int value);
void Delete(int value);
void Display();
int Rank(int value);
int RankX(int rank);
int Predecessor(int value);
int Successor(int value);
};
ScapegoatTree::ScapegoatTree() {
root = nullptr;
deletedCnt = 0;
}
void ScapegoatTree::Update(Node* node) {
node->cnt = (node->cnt < 0 ? 0 : node->cnt);
node->size = node->cnt;
if(node->leftChild != nullptr) {
node->size += node->leftChild->size;
node->leftChild->parent = node;
}
if(node->rightChild != nullptr) {
node->size += node->rightChild->size;
node->rightChild->parent = node;
}
}
bool ScapegoatTree::ShouldRes(Node* node) {
int biggerSize = -1;
if(node->leftChild != nullptr && node->leftChild->size > biggerSize) {
biggerSize = node->leftChild->size;
}
if(node->rightChild != nullptr && node->rightChild->size > biggerSize) {
biggerSize = node->rightChild->size;
}
return 1.0 * biggerSize > ALPHA * node->size;
}
Node* ScapegoatTree::BuildFromVec(std::vector<std::pair <int, int> > &vec, int l, int r) {
if(l > r) {
return nullptr;
}
Node* node = new Node(vec[(l + r) / 2].first, vec[(l + r) / 2].second);
node->leftChild = BuildFromVec(vec, l, (l + r) / 2 - 1);
node->rightChild = BuildFromVec(vec, (l + r) / 2 + 1, r);
Update(node);
return node;
}
void ScapegoatTree::InorderTraversal(Node* node, std::vector<std::pair<int, int> > &vec) {
if(node == nullptr) {
return;
}
InorderTraversal(node->leftChild, vec);
if(node->cnt > 0) {
vec.push_back(std::make_pair(node->value, node->cnt));
}
InorderTraversal(node->rightChild, vec);
delete node;
return;
}
Node* ScapegoatTree::Restructure(Node* node) {
std::vector<std::pair <int, int> > vec;
InorderTraversal(node, vec);
return BuildFromVec(vec, 0, vec.size() - 1);
}
Node* ScapegoatTree::HiddenInsert(Node* node, int value) {
if(node == nullptr) {
return new Node(value);
}
if(value < node->value) {
node->leftChild = HiddenInsert(node->leftChild, value);
}
else if(value > node->value) {
node->rightChild = HiddenInsert(node->rightChild, value);
}
else {
node->cnt++;
}
Update(node);
return node;
}
Node* ScapegoatTree::Check(Node* node, int value) {
if(node == nullptr) {
return nullptr;
}
if(ShouldRes(node)) {
return Restructure(node);
}
if(value < node->value) {
node->leftChild = Check(node->leftChild, value);
}
else if(value > node->value) {
node->rightChild = Check(node->rightChild, value);
}
Update(node);
return node;
}
void ScapegoatTree::Mark(Node* node, int value) {
if(node == nullptr) {
return;
}
if(value == node->value) {
if(node->cnt > 0) {
node->size--;
node->cnt--;
}
return;
}
if(value < node->value) {
Mark(node->leftChild, value);
}
else {
Mark(node->rightChild, value);
}
Update(node);
return;
}
void ScapegoatTree::HiddenDisplay(Node* node) {
if(node == nullptr) {
return;
}
HiddenDisplay(node->leftChild);
for(int i = 1; i <= node->cnt; i++) {
std::cout << node->value << ' ';
}
HiddenDisplay(node->rightChild);
return;
}
void ScapegoatTree::Insert(int value) {
root = HiddenInsert(root, value);
root = Check(root, value);
}
void ScapegoatTree::Delete(int value) {
deletedCnt++;
Mark(root, value);
if(deletedCnt > root->size / 2) {
root = Restructure(root);
deletedCnt = 0;
}
}
void ScapegoatTree::Display() {
HiddenDisplay(root);
std::cout << std::endl;
return;
}
int ScapegoatTree::Rank(int value) {
int cnt = 0;
Node* curr = root;
while(curr != nullptr) {
if(value < curr->value) {
curr = curr->leftChild;
}
else {
if(curr->leftChild != nullptr) {
cnt += curr->leftChild->size;
}
if(value == curr->value) {
return cnt + 1;
}
cnt += curr->cnt;
curr = curr->rightChild;
}
}
return cnt + 1;
}
int ScapegoatTree::RankX(int rank) {
Node* curr = root;
int cnt = 0;
while(curr != nullptr) {
int leftChildSize = 0;
if(curr->leftChild != nullptr) {
leftChildSize = curr->leftChild->size;
}
if(leftChildSize + cnt >= rank) {
curr = curr->leftChild;
}
else if(leftChildSize + cnt + curr->cnt < rank) {
cnt += leftChildSize;
cnt += curr->cnt;
curr = curr->rightChild;
}
else {
return curr->value;
}
}
}
int ScapegoatTree::Predecessor(int value) {
Node* curr = root, * prev = nullptr;
while(curr != nullptr) {
prev = curr;
if(curr->value < value) {
curr = curr->rightChild;
}
else {
curr = curr->leftChild;
}
}
if(prev->value < value) {
return prev->value;
}
if(prev->leftChild == nullptr) {
while(prev->parent != nullptr && prev == prev->parent->leftChild) {
prev = prev->parent;
}
return prev->parent->value;
}
else {
prev = prev->leftChild;
while(prev->rightChild != nullptr) {
prev = prev->rightChild;
}
return prev->value;
}
}
int ScapegoatTree::Successor(int value) {
Node* curr = root, * prev = nullptr;
while(curr != nullptr) {
prev = curr;
if(curr->value > value) {
curr = curr->leftChild;
}
else {
curr = curr->rightChild;
}
}
if(prev->value > value) {
return prev->value;
}
if(prev->rightChild == nullptr) {
while(prev->parent != nullptr && prev == prev->parent->rightChild) {
prev = prev->parent;
}
return prev->parent->value;
}
else {
prev = prev->rightChild;
while(prev->leftChild != nullptr) {
prev = prev->leftChild;
}
return prev->value;
}
}
}
int main() {
String::ScapegoatTree sgt;
int n;
cin >> n;
while(n--) {
int ope, val;
cin >> ope >> val;
switch (ope)
{
case 1:
sgt.Insert(val);
break;
case 2:
sgt.Delete(val);
break;
case 3:
cout << sgt.Rank(val) << endl;
break;
case 4:
cout << sgt.RankX(val) << endl;
break;
case 5:
cout << sgt.Predecessor(val) << endl;
break;
case 6:
cout << sgt.Successor(val) << endl;
break;
case 7:
sgt.Display();
break;
default:
break;
}
}
return 0;
}
一直都是5到11点WA不知道哪里除了问题/(ㄒoㄒ)/~~