{"id":23421494,"url":"https://github.com/eddieavd/natprolib","last_synced_at":"2025-04-12T14:06:45.882Z","repository":{"id":37598352,"uuid":"336123408","full_name":"eddieavd/natprolib","owner":"eddieavd","description":null,"archived":false,"fork":false,"pushed_at":"2024-01-25T14:36:32.000Z","size":351,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-01-25T15:51:46.809Z","etag":null,"topics":["competitive-programming","cplusplus","cpp20","standard-library","template-metaprogramming"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eddieavd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-02-05T00:49:14.000Z","updated_at":"2023-02-23T16:26:17.000Z","dependencies_parsed_at":"2024-01-25T15:46:44.544Z","dependency_job_id":null,"html_url":"https://github.com/eddieavd/natprolib","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddieavd%2Fnatprolib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddieavd%2Fnatprolib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddieavd%2Fnatprolib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddieavd%2Fnatprolib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eddieavd","download_url":"https://codeload.github.com/eddieavd/natprolib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230903862,"owners_count":18297817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["competitive-programming","cplusplus","cpp20","standard-library","template-metaprogramming"],"created_at":"2024-12-23T02:15:32.060Z","updated_at":"2024-12-23T02:15:32.694Z","avatar_url":"https://github.com/eddieavd.png","language":"C++","readme":"DEPRECATED  \nDevelopment continued here: https://github.com/eddieavd/uti\n\n\u003cpre\u003e\n                       █████                                 ████   ███  █████  \n                      ░░███                                 ░░███  ░░░  ░░███  \n ████████    ██████   ███████   ████████  ████████   ██████  ░███  ████  ░███████  \n░░███░░███  ░░░░░███ ░░░███░   ░░███░░███░░███░░███ ███░░███ ░███ ░░███  ░███░░███  \n ░███ ░███   ███████   ░███     ░███ ░███ ░███ ░░░ ░███ ░███ ░███  ░███  ░███ ░███  \n ░███ ░███  ███░░███   ░███ ███ ░███ ░███ ░███     ░███ ░███ ░███  ░███  ░███ ░███  \n ████ █████░░████████  ░░█████  ░███████  █████    ░░██████  █████ █████ ████████  \n░░░░ ░░░░░  ░░░░░░░░    ░░░░░   ░███░░░  ░░░░░      ░░░░░░  ░░░░░ ░░░░░ ░░░░░░░░  \n                                ░███  \n                                █████  \n                               ░░░░░  \n\u003c/pre\u003e\n\n**natprolib** is a library consisting of various containers and algorithms commonly used in competitive programming, implemented in a wannabe STL style to be more accessible for general use.  \n\n\n\n## table of contents\n\n* [range queries](#range_queries)\n    * [prefix array](#prefix_array)\n    * [prefix vector](#prefix_vector)\n    * [fenwick tree](#fenwick_tree)\n    * [segment tree](#segment_tree)\n* [algorithms](#algorithms)\n    * [algo1](#algo1)\n    * [algo2](#algo2)\n\n\n## \u003ca name = \"range_queries\"\u003e\u003c/a\u003e range queries\u003cbr/\u003e\n\nThe **range queries** header provides containers which are specially optimized for performing queries and updates on a list of elements.  \n\n#### \u003ca name = \"prefix_array\"\u003e\u003c/a\u003e prefix array\u003cbr/\u003e\n\nWhen tasked with processing a large amount of sum queries on a static array, the fastest approach is using a prefix sum array. \nEach value in the prefix sum array equals the sum of values in the original array up to that position, i.e., the value at position ```k``` equals ```sum( 0, k )```.  \nConsidering the array  \n```[ 1, 1, 1, 0, 1 ]```  \nthe corresponding prefix array would be  \n```[ 1, 2, 3, 3, 4 ]```.  \nThe prefix sum array can be constructed in _O( n )_ time.  \nSince the prefix array contains all values of ```sum( 0, k )```, we can calculate any value of ```sum( a, b )``` in _O( 1 )_ as follows:  \n```sum ( a, b ) = sum ( 0, b ) - sum( 0, a - 1 )``` for ```a != 0```  \n\n\n#### \u003ca name = \"prefix_vector\"\u003e\u003c/a\u003e prefix vector\u003cbr/\u003e\n\nThe prefix vector is a vector-like implementation of the prefix array.\n\n#### example\n\nLet's say you have a 2D vector of pixels. The following code constructs an integral image and performs a mean blur with a 32 pixel blur radius.\n\n```c++\n{\n    constexpr int blur_radius = 32 ;\n\n    using    image_t = npl::       vector\u003c npl::       vector\u003c unsigned char \u003e \u003e ;\n    using integral_t = npl::prefix_vector\u003c npl::prefix_vector\u003c unsigned long \u003e \u003e ;\n    \n    image_t      source_image = load_pixels();\n    image_t     blurred_image;\n    integral_t integral_image;\n\n    for( size_t i = 0; i \u003c source_image.height(); ++i )\n    {\n        integral_image.emplace_back( source_image.at( i ).begin(),\n                                     source_image.at( i ).end() );\n    }\n    for( size_t i = blur_radius / 2; i \u003c integral_image.height() - blur_radius / 2; ++i )\n    {\n        blurred_image.emplace_back();\n\n        for( size_t j = blur_radius / 2; j \u003c integral_image.width() - blur_radius / 2; ++i )\n        {\n            // sets value of new pixel to\n            // average value of pixels within blur_radius distance from current pixel\n            // sum of neighboring pixels calculated in constant time\n            blurred_image.at( i - blur_radius / 2, j - blur_radius / 2 ) =\n                integral_image.range( i - blur_radius / 2, j - blur_radius / 2,\n                                      i + blur_radius / 2, j + blur_radius / 2 )\n                / ( blur_radius * blur_radius );\n        }\n    }\n}\n```\n\n#### \u003ca name = \"fenwick_tree\"\u003e\u003c/a\u003e fenwick tree\u003cbr/\u003e\n\nThe Fenwick tree, also known as a binary indexed tree expands on the prefix array by providing _O(log n)_ updates to elements in the array. The payoff comes in the form of slower queries which now also run in _O(log n)_. Even though it's called a tree, it's usually represented as a one-indexed array.  \nLet ```p( k )``` denote the largest power of two that divides ```k```. The binary indexed tree is stored as an array ```tree``` such that  \n```tree[ k ] = sum( k - p( k ) + 1, k )```,  \ni.e., each position ```k``` contains the sum of values in a range of the original array whose length is ```p( k )``` and that ends at position ```k```.  \nFor example, since ```p( 6 ) = 2```, ```tree[ 6 ]``` contains the value of ```sum( 5, 6 )```.  \n_\u003csub\u003epics will go here i promise\u003c/sub\u003e_  \n  \nSince any range can be divided into ```log n``` of the ranges whose sums we calculated, any value of ```sum( 1, k )``` can be calculated in _O(log n)_ time.\nFor example, when calculating the sum on range ```[ 1, 7 ]```, we'd use the following ranges:  \n```sum( 1, 7 ) = sum( 1, 4 ) + sum( 5, 6 ) + sum( 7, 7 )```  \nJust like with the prefix array, we can use the same approach to calculating sums on a range ```[ a, b ]``` where ```a != 1```:  \n```sum( a, b ) = sum( 1, b ) - sum( 1, a - 1 )```  \nWhen updating values, several elements of the array need to be changed. However, since each array element belongs to log(_n_) ranges in the Fenwick tree, updating values can be done in _O(log n)_ time.  \n\n#### \u003ca name = \"segment_tree\"\u003e\u003c/a\u003e segment tree\u003cbr/\u003e\n\nThe segment tree is a data structure which allows for both range queries and single value updates, both in _O(log n)_ time. \nUnlike the previous entries which only support sum queries, the segment tree can be used for minimum/maximum queries, sum queries as well as with any other user-defined comparator (called ```parent_builder```).\u003csup\u003e1\u003c/sup\u003e  \nIt is implemented as a binary tree such that the nodes on the bottom level of the tree correspond to the array elements, and the other nodes contain information needed for processing range queries.  \n  \n![segment tree](https://github.com/eddieavd/img/blob/main/segtree.png)  \n\u003csup\u003eexample segment tree used for sum queries\u003c/sup\u003e  \nIt is assumed that the input array has a size equal to a power of two. If that is not the case, the original array is extended to the closest power of two. \nFor the sake of efficiency the tree is stored as an array of ```2n``` elements (where ```n``` is the size of the original array extended to the closest power of two) with ```tree[ 1 ]``` being the root node and ```tree[ 2k ]``` and ```tree[ 2k+1 ]``` being the children of ```tree[ k ]```.    \n\u003cbr/\u003e\u003csup\u003e1\u003c/sup\u003e The tests contain an example showing the usage of a segment tree for retreiving the second largest element on a specified range.  \n\n## \u003ca name = \"algorithms\"\u003e\u003c/a\u003e algorithms\u003cbr/\u003e\n\n#### \u003ca name = \"algo1\"\u003e\u003c/a\u003e algo1\u003cbr/\u003e\n#### \u003ca name = \"algo2\"\u003e\u003c/a\u003e algo2\u003cbr/\u003e\n\n## philosophy\n\n**natprolib** is a playground for learning about the STL and template metaprogramming by reimplementing the minimum set of STL features necessary to make natprolib independent.  \nIt's not necessarily intended to improve on all of those features, but suggestions for more elegant implementations are very welcome!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feddieavd%2Fnatprolib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feddieavd%2Fnatprolib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feddieavd%2Fnatprolib/lists"}