Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clarified the meaning of the "naive" and moved some solutions to the …
…main scoreboard according to the defined meaning
- Loading branch information
Showing
17 changed files
with
586 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
TARGETS = \ | ||
main-naive-java-like \ | ||
main-naive-raw \ | ||
main-naive-shared_ptr \ | ||
main-tuned-raw \ | ||
main-tuned-raw-with-pool \ | ||
main-tuned-unique_ptr | ||
|
||
.PHONY: all | ||
all: $(TARGETS:%=%-clang) $(TARGETS:%=%-clang-static) $(TARGETS:%=%-gcc) $(TARGETS:%=%-gcc-static) | ||
|
||
$(TARGETS:%=%-clang): %-clang : %.cpp | ||
clang++ -O3 --std=c++17 -flto -s -o $@ $< | ||
|
||
$(TARGETS:%=%-clang-static): %-clang-static : %.cpp | ||
/usr/bin/clang++ -O3 --std=c++17 -flto -s -static -o $@ $< | ||
|
||
$(TARGETS:%=%-gcc): %-gcc : %.cpp | ||
g++ -O3 --std=c++17 -flto -s -o $@ $< | ||
|
||
$(TARGETS:%=%-gcc-static): %-gcc-static : %.cpp | ||
g++ -O3 --std=c++17 -flto -s -static -o $@ $< | ||
|
||
.PHONY: clean | ||
clean: | ||
rm $(TARGETS:%=%-clang) $(TARGETS:%=%-clang-static) $(TARGETS:%=%-gcc) $(TARGETS:%=%-gcc-static) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#include <iostream> | ||
#include <memory> | ||
|
||
struct Node { | ||
explicit Node(int value) : value(value) {} | ||
|
||
int value; | ||
int priority = rand(); | ||
|
||
std::shared_ptr<Node> left; | ||
std::shared_ptr<Node> right; | ||
}; | ||
|
||
inline std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>> SplitBinary( | ||
std::shared_ptr<Node>&& input, int value) { | ||
if (!input) { | ||
return std::make_tuple(nullptr, nullptr); | ||
} else if (input->value < value) { | ||
auto [less, greater] = SplitBinary(std::move(input->right), value); | ||
input->right = std::move(less); | ||
return std::make_tuple(std::move(input), std::move(greater)); | ||
} else { | ||
auto [less, greater] = SplitBinary(std::move(input->left), value); | ||
input->left = std::move(greater); | ||
return std::make_tuple(std::move(less), std::move(input)); | ||
} | ||
} | ||
|
||
inline std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>, | ||
std::shared_ptr<Node>> | ||
Split(std::shared_ptr<Node>&& input, int value) { | ||
auto [less, greater_or_equal] = SplitBinary(std::move(input), value); | ||
auto [equal, greater] = SplitBinary(std::move(greater_or_equal), value + 1); | ||
return std::make_tuple(std::move(less), std::move(equal), std::move(greater)); | ||
} | ||
|
||
inline std::shared_ptr<Node>&& Merge(std::shared_ptr<Node>&& less, | ||
std::shared_ptr<Node>&& greater) { | ||
if (!less | !greater) { | ||
return std::move(less ? less : greater); | ||
} else if (less->priority < greater->priority) { | ||
less->right = Merge(std::move(less->right), std::move(greater)); | ||
return std::move(less); | ||
} else { | ||
greater->left = Merge(std::move(less), std::move(greater->left)); | ||
return std::move(greater); | ||
} | ||
} | ||
|
||
inline std::shared_ptr<Node>&& Merge(std::shared_ptr<Node>&& less, | ||
std::shared_ptr<Node>&& equal, | ||
std::shared_ptr<Node>&& greater) { | ||
return Merge(Merge(std::move(less), std::move(equal)), std::move(greater)); | ||
} | ||
|
||
class Treap { | ||
public: | ||
bool HasValue(int value) { | ||
auto [less, equal, greater] = Split(std::move(root_), value); | ||
const bool has_value = equal != nullptr; | ||
root_ = Merge(std::move(less), std::move(equal), std::move(greater)); | ||
return has_value; | ||
} | ||
|
||
void Insert(int value) { | ||
auto [less, equal, greater] = Split(std::move(root_), value); | ||
if (!equal) equal = std::make_shared<Node>(value); | ||
root_ = Merge(std::move(less), std::move(equal), std::move(greater)); | ||
} | ||
|
||
void Erase(int value) { | ||
auto [less, equal, greater] = Split(std::move(root_), value); | ||
root_ = Merge(std::move(less), std::move(greater)); | ||
} | ||
|
||
private: | ||
std::shared_ptr<Node> root_; | ||
}; | ||
|
||
int main() { | ||
srand(time(0)); | ||
|
||
Treap treap; | ||
int current = 5; | ||
int result = 0; | ||
for (int i = 1; i < 1000000; ++i) { | ||
const int mode = i % 3; | ||
current = (current * 57 + 43) % 10007; | ||
if (mode == 0) { | ||
treap.Insert(current); | ||
} else if (mode == 1) { | ||
treap.Erase(current); | ||
} else if (mode == 2) { | ||
result += treap.HasValue(current); | ||
} | ||
} | ||
std::cout << result; | ||
return 0; | ||
} |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
#include <iostream> | ||
#include <memory> | ||
|
||
#include <boost/pool/object_pool.hpp> | ||
#include <boost/pool/poolfwd.hpp> | ||
|
||
class Tree | ||
{ | ||
public: | ||
Tree() = default; | ||
~Tree() {} | ||
|
||
bool hasValue(int x); | ||
void insert(int x); | ||
void erase(int x); | ||
|
||
private: | ||
struct Node | ||
{ | ||
Node(int x): x(x) {} | ||
Node() {} | ||
|
||
int x = 0; | ||
int y = rand(); | ||
|
||
Node* left = nullptr; | ||
Node* right = nullptr; | ||
}; | ||
|
||
using NodePtr = Node*; | ||
|
||
static void merge(NodePtr lower, NodePtr greater, NodePtr& merged); | ||
static void merge(NodePtr lower, NodePtr equal, NodePtr greater, NodePtr& merged); | ||
static void split(NodePtr orig, NodePtr& lower, NodePtr& greaterOrEqual, int val); | ||
static void split(NodePtr orig, NodePtr& lower, NodePtr& equal, NodePtr& greater, int val); | ||
|
||
void clear(NodePtr node); | ||
|
||
NodePtr mRoot = nullptr; | ||
boost::object_pool<Node> mNodePool = boost::object_pool<Node>(); | ||
}; | ||
|
||
void Tree::clear(NodePtr node) | ||
{ | ||
if(!node) | ||
return; | ||
|
||
clear(node->left); | ||
clear(node->right); | ||
mNodePool.destroy(node); | ||
} | ||
|
||
bool Tree::hasValue(int x) | ||
{ | ||
NodePtr lower, equal, greater; | ||
split(mRoot, lower, equal, greater, x); | ||
bool res = equal != nullptr; | ||
merge(lower, equal, greater, mRoot); | ||
return res; | ||
} | ||
|
||
void Tree::insert(int x) | ||
{ | ||
NodePtr lower, equal, greater; | ||
split(mRoot, lower, equal, greater, x); | ||
if(!equal) | ||
equal = mNodePool.construct(x); | ||
|
||
merge(lower, equal, greater, mRoot); | ||
} | ||
|
||
void Tree::erase(int x) | ||
{ | ||
NodePtr lower, equal, greater; | ||
split(mRoot, lower, equal, greater, x); | ||
merge(lower, greater, mRoot); | ||
clear(equal); | ||
} | ||
|
||
void Tree::merge(NodePtr lower, NodePtr greater, NodePtr& merged) | ||
{ | ||
if(!lower) | ||
{ | ||
merged = greater; | ||
return; | ||
} | ||
|
||
if(!greater) | ||
{ | ||
merged = lower; | ||
return; | ||
} | ||
|
||
if(lower->y < greater->y) | ||
{ | ||
merged = lower; | ||
merge(merged->right, greater, merged->right); | ||
} | ||
else | ||
{ | ||
merged = greater; | ||
merge(lower, merged->left, merged->left); | ||
} | ||
} | ||
|
||
void Tree::merge(NodePtr lower, NodePtr equal, NodePtr greater, NodePtr& merged) | ||
{ | ||
merge(lower, equal, merged); | ||
merge(merged, greater, merged); | ||
} | ||
|
||
void Tree::split(NodePtr orig, NodePtr& lower, NodePtr& greaterOrEqual, int val) | ||
{ | ||
if(!orig) | ||
{ | ||
lower = greaterOrEqual = nullptr; | ||
return; | ||
} | ||
|
||
if(orig->x < val) | ||
{ | ||
lower = orig; | ||
split(lower->right, lower->right, greaterOrEqual, val); | ||
} | ||
else | ||
{ | ||
greaterOrEqual = orig; | ||
split(greaterOrEqual->left, lower, greaterOrEqual->left, val); | ||
} | ||
} | ||
|
||
void Tree::split(NodePtr orig, NodePtr& lower, NodePtr& equal, NodePtr& greater, int val) | ||
{ | ||
NodePtr equalOrGreater; | ||
split(orig, lower, equalOrGreater, val); | ||
split(equalOrGreater, equal, greater, val + 1); | ||
} | ||
|
||
int main() | ||
{ | ||
srand(time(0)); | ||
|
||
Tree tree; | ||
|
||
int cur = 5; | ||
int res = 0; | ||
|
||
for(int i = 1; i < 1000000; i++) | ||
{ | ||
int mode = i % 3; | ||
cur = (cur * 57 + 43) % 10007; | ||
if(mode == 0) | ||
{ | ||
tree.insert(cur); | ||
} | ||
else if(mode == 1) | ||
{ | ||
tree.erase(cur); | ||
} | ||
else if(mode == 2) | ||
{ | ||
res += tree.hasValue(cur); | ||
} | ||
} | ||
std::cout << res; | ||
return 0; | ||
} |
Oops, something went wrong.