Merge branch 'master' into master

This commit is contained in:
David Leal 2021-10-18 11:55:42 -05:00 committed by GitHub
commit 8cdfd84c98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 318 additions and 52 deletions

View File

@ -61,6 +61,7 @@
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h) * [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h)
* [Stack Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_array.cpp) * [Stack Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_array.cpp)
* [Stack Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_linked_list.cpp) * [Stack Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_linked_list.cpp)
* [Stack Using Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_queue.cpp)
* [Test Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_queue.cpp) * [Test Queue](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_queue.cpp)
* [Test Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_stack.cpp) * [Test Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_stack.cpp)
* [Test Stack Students](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_stack_students.cpp) * [Test Stack Students](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/test_stack_students.cpp)

View File

@ -0,0 +1,126 @@
/**
* @brief Stack Data Structure Using the Queue Data Structure
* @details
* Using 2 Queues inside the Stack class, we can easily implement Stack
* data structure with heavy computation in push function.
*
* References used: [StudyTonight](https://www.studytonight.com/data-structures/stack-using-queue)
* @author [tushar2407](https://github.com/tushar2407)
*/
#include <iostream> /// for IO operations
#include <queue> /// for queue data structure
#include <cassert> /// for assert
/**
* @namespace data_strcutres
* @brief Data structures algorithms
*/
namespace data_structures {
/**
* @namespace stack_using_queue
* @brief Functions for the [Stack Using Queue](https://www.studytonight.com/data-structures/stack-using-queue) implementation
*/
namespace stack_using_queue {
/**
* @brief Stack Class implementation for basic methods of Stack Data Structure.
*/
struct Stack
{
std::queue<int64_t> main_q; ///< stores the current state of the stack
std::queue<int64_t> auxiliary_q; ///< used to carry out intermediate operations to implement stack
uint32_t current_size = 0; ///< stores the current size of the stack
/**
* Returns the top most element of the stack
* @returns top element of the queue
*/
int top()
{
return main_q.front();
}
/**
* @brief Inserts an element to the top of the stack.
* @param val the element that will be inserted into the stack
* @returns void
*/
void push(int val)
{
auxiliary_q.push(val);
while(!main_q.empty())
{
auxiliary_q.push(main_q.front());
main_q.pop();
}
swap(main_q, auxiliary_q);
current_size++;
}
/**
* @brief Removes the topmost element from the stack
* @returns void
*/
void pop()
{
if(main_q.empty()) {
return;
}
main_q.pop();
current_size--;
}
/**
* @brief Utility function to return the current size of the stack
* @returns current size of stack
*/
int size()
{
return current_size;
}
};
} // namespace stack_using_queue
} // namespace data_structures
/**
* @brief Self-test implementations
* @returns void
*/
static void test()
{
data_structures::stack_using_queue::Stack s;
s.push(1); /// insert an element into the stack
s.push(2); /// insert an element into the stack
s.push(3); /// insert an element into the stack
assert(s.size()==3); /// size should be 3
assert(s.top()==3); /// topmost element in the stack should be 3
s.pop(); /// remove the topmost element from the stack
assert(s.top()==2); /// topmost element in the stack should now be 2
s.pop(); /// remove the topmost element from the stack
assert(s.top()==1);
s.push(5); /// insert an element into the stack
assert(s.top()==5); /// topmost element in the stack should now be 5
s.pop(); /// remove the topmost element from the stack
assert(s.top()==1); /// topmost element in the stack should now be 1
assert(s.size()==1); /// size should be 1
}
/**
* @brief Main function
* Creates a stack and pushed some value into it.
* Through a series of push and pop functions on stack,
* it demostrates the functionality of the custom stack
* declared above.
* @returns 0 on exit
*/
int main()
{
test(); // run self-test implementations
return 0;
}

View File

@ -1,79 +1,218 @@
//#include <bits/stdc++.h> /**
#incldue < iostream > * @file
#define MAX 4000000 * @brief Implementation of [Segment Tree]
using namespace std; * (https://en.wikipedia.org/wiki/Segment_tree) data structure
typedef long long ll; *
void ConsTree(ll arr[], ll segtree[], ll low, ll high, ll pos) { * @details
* A segment tree, also known as a statistic tree, is a tree data structure used
* for storing information about intervals, or segments. Its classical version
* allows querying which of the stored segments contain a given point, but our
* modification allows us to perform (query) any binary operation on any range
* in the array in O(logN) time. Here, we have used addition (+).
* For range updates, we have used lazy propagation.
*
* * Space Complexity : O(NlogN) \n
* * Build Time Complexity : O(NlogN) \n
* * Query Time Complexity : O(logN) \n
*
* @author [Madhav Gaba](https://github.com/madhavgaba)
* @author [Soham Roy](https://github.com/sohamroy19)
*/
#include <cassert> /// for assert
#include <cmath> /// for log2
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @brief Constructs the initial segment tree
*
* @param arr input to construct the tree out of
* @param segtree the segment tree
* @param low inclusive lowest index of arr to begin at
* @param high inclusive highest index of arr to end at
* @param pos index of segtree to fill (eg. root node)
* @returns void
*/
void ConsTree(const std::vector<int64_t> &arr, std::vector<int64_t> *segtree,
uint64_t low, uint64_t high, uint64_t pos) {
if (low == high) { if (low == high) {
segtree[pos] = arr[low]; (*segtree)[pos] = arr[low];
return; return;
} }
ll mid = (low + high) / 2;
uint64_t mid = (low + high) / 2;
ConsTree(arr, segtree, low, mid, 2 * pos + 1); ConsTree(arr, segtree, low, mid, 2 * pos + 1);
ConsTree(arr, segtree, mid + 1, high, 2 * pos + 2); ConsTree(arr, segtree, mid + 1, high, 2 * pos + 2);
segtree[pos] = segtree[2 * pos + 1] + segtree[2 * pos + 2]; (*segtree)[pos] = (*segtree)[2 * pos + 1] + (*segtree)[2 * pos + 2];
} }
ll query(ll segtree[], ll lazy[], ll qlow, ll qhigh, ll low, ll high, ll pos) {
if (low > high) /**
* @brief Returns the sum of all elements in a range
*
* @param segtree the segment tree
* @param lazy for lazy propagation
* @param qlow lower index of the required query
* @param qhigh higher index of the required query
* @param low lower index of query for this function call
* @param high higher index of query for this function call
* @param pos index of segtree to consider (eg. root node)
* @return result of the range query for this function call
*/
int64_t query(std::vector<int64_t> *segtree, std::vector<int64_t> *lazy,
uint64_t qlow, uint64_t qhigh, uint64_t low, uint64_t high,
uint64_t pos) {
if (low > high || qlow > high || low > qhigh) {
return 0; return 0;
if (qlow > high || qhigh < low)
return 0;
if (lazy[pos] != 0) {
segtree[pos] += lazy[pos] * (high - low + 1);
if (low != high) {
lazy[2 * pos + 1] += lazy[pos];
lazy[2 * pos + 2] += lazy[pos];
}
lazy[pos] = 0;
} }
if (qlow <= low && qhigh >= high)
return segtree[pos]; if ((*lazy)[pos] != 0) {
ll mid = (low + high) / 2; (*segtree)[pos] += (*lazy)[pos] * (high - low + 1);
if (low != high) {
(*lazy)[2 * pos + 1] += (*lazy)[pos];
(*lazy)[2 * pos + 2] += (*lazy)[pos];
}
(*lazy)[pos] = 0;
}
if (qlow <= low && qhigh >= high) {
return (*segtree)[pos];
}
uint64_t mid = (low + high) / 2;
return query(segtree, lazy, qlow, qhigh, low, mid, 2 * pos + 1) + return query(segtree, lazy, qlow, qhigh, low, mid, 2 * pos + 1) +
query(segtree, lazy, qlow, qhigh, mid + 1, high, 2 * pos + 2); query(segtree, lazy, qlow, qhigh, mid + 1, high, 2 * pos + 2);
} }
void update(ll segtree[], ll lazy[], ll start, ll end, ll delta, ll low,
ll high, ll pos) { /**
if (low > high) * @brief Updates a range of the segment tree
*
* @param segtree the segment tree
* @param lazy for lazy propagation
* @param start lower index of the required query
* @param end higher index of the required query
* @param delta integer to add to each element of the range
* @param low lower index of query for this function call
* @param high higher index of query for this function call
* @param pos index of segtree to consider (eg. root node)
* @returns void
*/
void update(std::vector<int64_t> *segtree, std::vector<int64_t> *lazy,
int64_t start, int64_t end, int64_t delta, uint64_t low,
uint64_t high, uint64_t pos) {
if (low > high) {
return; return;
if (lazy[pos] != 0) {
segtree[pos] += lazy[pos] * (high - low + 1);
if (low != high) {
lazy[2 * pos + 1] += lazy[pos];
lazy[2 * pos + 2] += lazy[pos];
}
lazy[pos] = 0;
} }
if (start > high || end < low)
if ((*lazy)[pos] != 0) {
(*segtree)[pos] += (*lazy)[pos] * (high - low + 1);
if (low != high) {
(*lazy)[2 * pos + 1] += (*lazy)[pos];
(*lazy)[2 * pos + 2] += (*lazy)[pos];
}
(*lazy)[pos] = 0;
}
if (start > high || end < low) {
return; return;
}
if (start <= low && end >= high) { if (start <= low && end >= high) {
segtree[pos] += delta * (high - low + 1); (*segtree)[pos] += delta * (high - low + 1);
if (low != high) { if (low != high) {
lazy[2 * pos + 1] += delta; (*lazy)[2 * pos + 1] += delta;
lazy[2 * pos + 2] += delta; (*lazy)[2 * pos + 2] += delta;
} }
return; return;
} }
ll mid = (low + high) / 2;
uint64_t mid = (low + high) / 2;
update(segtree, lazy, start, end, delta, low, mid, 2 * pos + 1); update(segtree, lazy, start, end, delta, low, mid, 2 * pos + 1);
update(segtree, lazy, start, end, delta, mid + 1, high, 2 * pos + 2); update(segtree, lazy, start, end, delta, mid + 1, high, 2 * pos + 2);
segtree[pos] = segtree[2 * pos + 1] + segtree[2 * pos + 2]; (*segtree)[pos] = (*segtree)[2 * pos + 1] + (*segtree)[2 * pos + 2];
} }
/**
* @brief Self-test implementation
*
* @returns void
*/
static void test() {
int64_t max = static_cast<int64_t>(2 * pow(2, ceil(log2(7))) - 1);
assert(max == 15);
std::vector<int64_t> arr{1, 2, 3, 4, 5, 6, 7}, lazy(max), segtree(max);
ConsTree(arr, &segtree, 0, 7 - 1, 0);
assert(query(&segtree, &lazy, 1, 5, 0, 7 - 1, 0) == 2 + 3 + 4 + 5 + 6);
update(&segtree, &lazy, 2, 4, 1, 0, 7 - 1, 0);
assert(query(&segtree, &lazy, 1, 5, 0, 7 - 1, 0) == 2 + 4 + 5 + 6 + 6);
update(&segtree, &lazy, 0, 6, -2, 0, 7 - 1, 0);
assert(query(&segtree, &lazy, 0, 4, 0, 7 - 1, 0) == -1 + 0 + 2 + 3 + 4);
}
/**
* @brief Main function
*
* @return 0 on exit
*/
int main() { int main() {
ll n, c; test(); // run self-test implementations
scanf("%lld %lld", &n, &c);
ll arr[n] = {0}, p, q, v, choice; std::cout << "Enter number of elements: ";
ll segtree[MAX], lazy[MAX] = {0};
ConsTree(arr, segtree, 0, n - 1, 0); uint64_t n = 0;
while (c--) { std::cin >> n;
scanf("%lld", &choice);
if (choice == 0) { uint64_t max = static_cast<uint64_t>(2 * pow(2, ceil(log2(n))) - 1);
scanf("%lld %lld %lld", &p, &q, &v); std::vector<int64_t> arr(n), lazy(max), segtree(max);
update(segtree, lazy, p - 1, q - 1, v, 0, n - 1, 0);
} else { int choice = 0;
scanf("%lld %lld", &p, &q); std::cout << "\nDo you wish to enter each number?:\n"
printf("%lld\n", query(segtree, lazy, p - 1, q - 1, 0, n - 1, 0)); "1: Yes\n"
"0: No (default initialize them to 0)\n";
std::cin >> choice;
if (choice == 1) {
std::cout << "Enter " << n << " numbers:\n";
for (int i = 1; i <= n; i++) {
std::cout << i << ": ";
std::cin >> arr[i];
} }
} }
ConsTree(arr, &segtree, 0, n - 1, 0);
do {
std::cout << "\nMake your choice:\n"
"1: Range update (input)\n"
"2: Range query (output)\n"
"0: Exit\n";
std::cin >> choice;
if (choice == 1) {
std::cout << "Enter 1-indexed lower bound, upper bound & value:\n";
uint64_t p = 1, q = 1, v = 0;
std::cin >> p >> q >> v;
update(&segtree, &lazy, p - 1, q - 1, v, 0, n - 1, 0);
} else if (choice == 2) {
std::cout << "Enter 1-indexed lower bound & upper bound:\n";
uint64_t p = 1, q = 1;
std::cin >> p >> q;
std::cout << query(&segtree, &lazy, p - 1, q - 1, 0, n - 1, 0);
std::cout << "\n";
}
} while (choice > 0);
return 0; return 0;
} }