├── .gitattributes ├── .gitignore ├── AlgorithmTest ├── AlgorithmTest.vcxproj ├── AlgorithmTest.vcxproj.filters ├── DataStructuresTest.cpp ├── FamousProblemsTest.cpp ├── GraphTest.cpp ├── MathTest.cpp ├── SortingTest.cpp ├── StringTest.cpp ├── packages.config ├── pch.cpp ├── pch.h └── test.cpp ├── Algorithms.sln ├── Algorithms ├── Algorithms.vcxproj ├── Algorithms.vcxproj.filters ├── Source_processed.cpp ├── include │ ├── DataStructures │ │ ├── FenwickTree.h │ │ ├── LazySegmentTree.h │ │ ├── RedBlackTree.h │ │ ├── SegmentTree.h │ │ ├── SkipList.h │ │ ├── SparseTable.h │ │ └── Trie.h │ ├── Defines.h │ ├── FamousProblems │ │ ├── AllProblems.h │ │ └── Sudoku.h │ ├── Geometry │ │ └── Geometry.h │ ├── Graph │ │ ├── Bipartite.h │ │ ├── Bridges.h │ │ ├── ChromaticNumber.h │ │ ├── Components.h │ │ ├── CutPoints.h │ │ ├── CycleChecker.h │ │ ├── DSU.h │ │ ├── Dijkstra.h │ │ ├── Euler.h │ │ ├── FloydWarshall.h │ │ ├── FordBellman.h │ │ ├── Graph.h │ │ ├── Khun.h │ │ ├── Kruskal.h │ │ ├── LCA.h │ │ ├── PruferCode.h │ │ ├── StrongComponents.h │ │ └── Toposort.h │ ├── Math │ │ └── Math.h │ ├── Sortings │ │ └── Sorting.h │ ├── Strings │ │ ├── KnuthMorrisPratt.h │ │ ├── PrefixFunction.h │ │ ├── StringHashing.h │ │ └── ZFunction.h │ ├── Utils.h │ └── Utils.hpp └── src │ ├── DataStructures │ └── Trie.cpp │ ├── Geometry │ └── Geometry.cpp │ ├── Graph │ ├── Bipartite.cpp │ ├── Bridges.cpp │ ├── ChromaticNumber.cpp │ ├── Components.cpp │ ├── CutPoints.cpp │ ├── CycleChecker.cpp │ ├── DSU.cpp │ ├── Dijkstra.cpp │ ├── Euler.cpp │ ├── FloydWarshall.cpp │ ├── FordBellman.cpp │ ├── Graph.cpp │ ├── Khun.cpp │ ├── Kruskal.cpp │ ├── LCA.cpp │ ├── PruferCode.cpp │ ├── StrongComponents.cpp │ └── Toposort.cpp │ ├── Math │ └── Math.cpp │ └── Strings │ ├── KnuthMorrisPratt.cpp │ ├── PrefixFunction.cpp │ ├── StringHashing.cpp │ └── ZFunction.cpp ├── CodePreprocessor ├── CodePreprocessor.vcxproj ├── CodePreprocessor.vcxproj.filters ├── FileProcessor.cpp ├── FileProcessor.h ├── FileSearcher.cpp ├── FileSearcher.h ├── Source.cpp └── Source_processed.cpp ├── Coding ├── Coding.vcxproj ├── Coding.vcxproj.filters ├── Source.cpp ├── Source_processed.cpp ├── input.txt └── package-lock.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /AlgorithmTest/AlgorithmTest.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {bbffcc52-30d0-4e22-8e51-41245d12e1f1} 23 | Win32Proj 24 | 10.0 25 | Application 26 | v142 27 | Unicode 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | $(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 37 | $(SolutionDir)packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\include;$(SolutionDir)Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath) 38 | 39 | 40 | $(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 41 | $(SolutionDir)\Algorithms\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\include;$(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath) 42 | 43 | 44 | $(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 45 | $(SolutionDir)\Algorithms\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\include;$(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath) 46 | 47 | 48 | $(SolutionDir)\Algorithms\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\include;$(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath) 49 | $(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Create 64 | Create 65 | Create 66 | Create 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Use 80 | pch.h 81 | Disabled 82 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 83 | true 84 | EnableFastChecks 85 | MultiThreadedDebugDLL 86 | Level3 87 | 88 | 89 | true 90 | Console 91 | Algorithms.lib;$(MSBuildThisFileDirectory)..\packages\.*\lib\native\v140\windesktop\msvcstl\static\rt-dyn\x86\Debug\gtest_main.lib;%(AdditionalDependencies) 92 | $(ProjectDir)../x64/Debug 93 | 94 | 95 | echo $(ExecutableDir)..\Algorithms\include 96 | 97 | 98 | 99 | 100 | Use 101 | pch.h 102 | Disabled 103 | X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | EnableFastChecks 106 | MultiThreadedDebugDLL 107 | Level3 108 | false 109 | 16Bytes 110 | 111 | 112 | true 113 | Console 114 | Algorithms.lib;gtest_main.lib;gtest.lib;%(AdditionalDependencies) 115 | $(ProjectDir)../x64/Debug;$(SolutionDir)packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\lib\native\v140\windesktop\msvcstl\static\rt-dyn\x64\Debug 116 | 117 | 118 | 119 | 120 | Use 121 | pch.h 122 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 123 | MultiThreadedDLL 124 | Level3 125 | ProgramDatabase 126 | 127 | 128 | true 129 | Console 130 | true 131 | true 132 | Algorithms.lib;$(MSBuildThisFileDirectory)..\packages\.*\lib\native\v140\windesktop\msvcstl\static\rt-dyn\x86\Release\gtest_main.lib;%(AdditionalDependencies) 133 | $(ProjectDir)../x64/Debug 134 | 135 | 136 | echo $(ExecutableDir)..\Algorithms\include 137 | 138 | 139 | 140 | 141 | Use 142 | pch.h 143 | X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 144 | MultiThreadedDLL 145 | Level3 146 | ProgramDatabase 147 | 148 | 149 | true 150 | Console 151 | true 152 | true 153 | Algorithms.lib;$(MSBuildThisFileDirectory)..\..\lib\native\v140\windesktop\msvcstl\static\rt-dyn\x64\Release\gtest_main.lib;%(AdditionalDependencies) 154 | $(ProjectDir)../x64/Debug 155 | 156 | 157 | 158 | 159 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /AlgorithmTest/AlgorithmTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Tests 7 | 8 | 9 | Tests 10 | 11 | 12 | Tests 13 | 14 | 15 | Tests 16 | 17 | 18 | Tests 19 | 20 | 21 | Tests 22 | 23 | 24 | Tests 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {d98e02ef-27de-4326-98c0-e1b8a977eb72} 36 | 37 | 38 | -------------------------------------------------------------------------------- /AlgorithmTest/DataStructuresTest.cpp: -------------------------------------------------------------------------------- 1 | #include"pch.h" 2 | 3 | #include"DataStructures/SegmentTree.h" 4 | #include"DataStructures/Trie.h" 5 | #include"DataStructures/SparseTable.h" 6 | #include"DataStructures/FenwickTree.h" 7 | #include 8 | #include 9 | 10 | int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } 11 | int sum_on_vector(const std::vector& vec, int i, int j) 12 | { 13 | int sum = 0; 14 | while (i <= j) 15 | { 16 | sum += vec[i++]; 17 | } 18 | return sum; 19 | } 20 | int mul_on_vector(const std::vector& vec, int i, int j) 21 | { 22 | int mul = 1; 23 | while (i <= j) 24 | { 25 | mul *= vec[i++]; 26 | } 27 | return mul; 28 | } 29 | int min_on_vector(const std::vector& vec, int i, int j) 30 | { 31 | int g = vec[i++]; 32 | while (i <= j) 33 | { 34 | g = std::min(g, vec[i++]); 35 | } 36 | return g; 37 | } 38 | int max_on_vector(const std::vector& vec, int i, int j) 39 | { 40 | int g = vec[i++]; 41 | while (i <= j) 42 | { 43 | g = std::max(g, vec[i++]); 44 | } 45 | return g; 46 | } 47 | int gcd_on_vector(const std::vector& vec, int i, int j) 48 | { 49 | int g = vec[i++]; 50 | while (i <= j) 51 | { 52 | g = gcd(g, vec[i++]); 53 | } 54 | return g; 55 | } 56 | 57 | 58 | 59 | TEST(SegmentTreeTest, DataStructures) 60 | { 61 | std::mt19937 rand_function(time(0)); 62 | // sum 63 | for (int i = 0; i < 10; ++i) 64 | { 65 | std::vector vec = getRandomVector(1000, 1, 100); 66 | algo::SegmentTree tree(vec, std::plus(), 0); 67 | tree.build_tree(); 68 | std::uniform_int_distribution uid(0, vec.size() - 1); 69 | int a = uid(rand_function); 70 | int b = uid(rand_function); 71 | if (a > b) 72 | std::swap(a, b); 73 | EXPECT_EQ(tree.query(a, b), sum_on_vector(vec, a, b)); 74 | tree.update(a, vec[a] + 1); 75 | } 76 | // product 77 | for (int i = 0; i < 10; ++i) 78 | { 79 | std::vector vec = getRandomVector(1000, -1, 1); 80 | algo::SegmentTree tree(vec, std::multiplies(), 1); 81 | tree.build_tree(); 82 | std::uniform_int_distribution uid(0, vec.size() - 1); 83 | int a = uid(rand_function); 84 | int b = uid(rand_function); 85 | if (a > b) 86 | std::swap(a, b); 87 | EXPECT_EQ(tree.query(a, b), mul_on_vector(vec, a, b)); 88 | tree.update(a, vec[a] + 1); 89 | } 90 | // min 91 | for (int i = 0; i < 10; ++i) 92 | { 93 | std::vector vec = getRandomVector(1000, -1111, 1111); 94 | const int& (*operation)(const int&, const int&) = std::min; 95 | algo::SegmentTree tree(vec, operation, 1111); 96 | tree.build_tree(); 97 | std::uniform_int_distribution uid(0, vec.size() - 1); 98 | int a = uid(rand_function); 99 | int b = uid(rand_function); 100 | if (a > b) 101 | std::swap(a, b); 102 | EXPECT_EQ(tree.query(a, b), min_on_vector(vec, a, b)); 103 | tree.update(a, vec[a] + 1); 104 | } 105 | // max 106 | for (int i = 0; i < 10; ++i) 107 | { 108 | std::vector vec = getRandomVector(1000, -1111, 1111); 109 | const int& (*operation)(const int&, const int&) = std::max; 110 | algo::SegmentTree tree(vec, operation, -1111, algo::SegmentTree::UpdateType::Sum); 111 | tree.build_tree(); 112 | std::uniform_int_distribution uid(0, vec.size() - 1); 113 | int a = uid(rand_function); 114 | int b = uid(rand_function); 115 | if (a > b) 116 | std::swap(a, b); 117 | EXPECT_EQ(tree.query(a, b), max_on_vector(vec, a, b)); 118 | tree.update(a, vec[a] + 1); 119 | } 120 | // gcd 121 | for (int i = 0; i < 10; ++i) 122 | { 123 | std::vector vec = getRandomVector(1000, 1, 100); 124 | algo::SegmentTree tree(vec, [](int a, int b) { return gcd(a, b); }, 0); 125 | tree.build_tree(); 126 | std::uniform_int_distribution uid(0, vec.size() - 1); 127 | int a = uid(rand_function); 128 | int b = uid(rand_function); 129 | if (a > b) 130 | std::swap(a, b); 131 | EXPECT_EQ(tree.query(a, b), gcd_on_vector(vec, a, b)); 132 | tree.update(a, vec[a] + 1); 133 | } 134 | } 135 | 136 | 137 | TEST(LazySegmentTreeTest, DataStructures) 138 | { 139 | std::mt19937 rand_function(time(0)); 140 | // sum 141 | for (int i = 0; i < 10; ++i) 142 | { 143 | std::vector vec = getRandomVector(1000, 1, 100); 144 | algo::SegmentTree tree(vec, std::plus(), 0, algo::SegmentTree::UpdateType::Sum); 145 | std::uniform_int_distribution uid(0, vec.size() - 1); 146 | int a = uid(rand_function); 147 | int b = uid(rand_function); 148 | if (a > b) 149 | std::swap(a, b); 150 | int value = uid(rand_function); 151 | tree.update(a, b, value); 152 | for (int i = a; i <= b; ++i) 153 | { 154 | vec[i] += value; 155 | } 156 | EXPECT_EQ(tree.query(a, b), sum_on_vector(vec, a, b)); 157 | } 158 | } 159 | 160 | TEST(FenwickTreeTest, DataStructures) 161 | { 162 | std::mt19937 rand_function(time(0)); 163 | // sum 164 | for (int i = 0; i < 10; ++i) 165 | { 166 | std::vector vec = getRandomVector(1000, 1, 100); 167 | algo::FenwickTree tree(vec); 168 | tree.build_tree(); 169 | std::uniform_int_distribution uid(0, vec.size() - 1); 170 | int a = uid(rand_function); 171 | int b = uid(rand_function); 172 | if (a > b) 173 | std::swap(a, b); 174 | EXPECT_EQ(tree.query(a, b), sum_on_vector(vec, a, b)); 175 | tree.update(a, vec[a] + 1); 176 | } 177 | } 178 | 179 | 180 | TEST(TrieTest, DataStructures) 181 | { 182 | algo::Trie trie; 183 | std::vector words = 184 | { 185 | "hello", 186 | "abba", 187 | "abacaba" 188 | }; 189 | for (int i = 0; i < words.size(); ++i) 190 | { 191 | for (int j = 0; j < words[i].size(); ++j) 192 | { 193 | trie.add_word(words[i].substr(j)); 194 | } 195 | } 196 | EXPECT_TRUE(trie.find_word("a")); 197 | EXPECT_FALSE(trie.find_word("b")); 198 | EXPECT_FALSE(trie.find_word("ell")); 199 | EXPECT_FALSE(trie.find_word("aca")); 200 | EXPECT_FALSE(trie.find_word("abaca")); 201 | EXPECT_TRUE(trie.find_word("acaba")); 202 | EXPECT_TRUE(trie.find_word("hello")); 203 | EXPECT_TRUE(trie.find_word("ello")); 204 | EXPECT_TRUE(trie.find_word("llo")); 205 | EXPECT_TRUE(trie.find_word("lo")); 206 | EXPECT_TRUE(trie.find_word("o")); 207 | 208 | } 209 | 210 | 211 | TEST(SparseTableTest, DataStructures) 212 | { 213 | std::mt19937 rand_function(time(0)); 214 | for (int i = 0; i < 10; ++i) 215 | { 216 | std::vector vec = getRandomVector(1000, 10, 100); 217 | algo::SparseTable table(vec); 218 | std::uniform_int_distribution uid(0, vec.size() - 1); 219 | int a = uid(rand_function); 220 | int b = uid(rand_function); 221 | if (a > b) 222 | std::swap(a, b); 223 | 224 | EXPECT_EQ(table.query(a, b), min_on_vector(vec, a, b)); 225 | } 226 | 227 | } -------------------------------------------------------------------------------- /AlgorithmTest/FamousProblemsTest.cpp: -------------------------------------------------------------------------------- 1 | #include"pch.h" 2 | 3 | #include"FamousProblems\AllProblems.h" 4 | 5 | #include 6 | #include 7 | 8 | 9 | TEST(MatrixMultiplicationTest, FamousProblemsTest) 10 | { 11 | EXPECT_EQ( 12 | algo::MatrixMultProblem({ {10, 20}, {20, 30}, {30, 40}, {40, 30} }), 13 | 30000 14 | ); 15 | EXPECT_EQ( 16 | algo::MatrixMultProblem({ {40, 20}, {20, 30}, {30, 10}, {10, 30} }), 17 | 26000 18 | ); 19 | EXPECT_EQ( 20 | algo::MatrixMultProblem({ {10, 20}, {20, 30} }), 21 | 6000 22 | ); 23 | } 24 | 25 | TEST(LivenshteinTest, FamousProblemsTest) 26 | { 27 | { 28 | std::string str1 = "dye"; 29 | std::string str2 = "day"; 30 | EXPECT_EQ( 31 | algo::Livenshtein(str1, str2), 32 | 2 33 | ); 34 | } 35 | { 36 | std::string str1 = "exponential"; 37 | std::string str2 = "polynomial"; 38 | EXPECT_EQ( 39 | algo::Livenshtein(str1, str2), 40 | 6 41 | ); 42 | } 43 | { 44 | std::string str1 = "kitten"; 45 | std::string str2 = "sitting"; 46 | EXPECT_EQ( 47 | algo::Livenshtein(str1, str2), 48 | 3 49 | ); 50 | } 51 | { 52 | std::string str1 = "saturday"; 53 | std::string str2 = "sunday"; 54 | EXPECT_EQ( 55 | algo::Livenshtein(str1, str2), 56 | 3 57 | ); 58 | } 59 | } 60 | TEST(LISTest, FamousProblemsTest) 61 | { 62 | { 63 | std::vector arr{ 0, 8, 4, 12, 2, 10, 6, 64 | 14, 1, 9, 5, 13, 3, 11, 7, 15 }; 65 | EXPECT_EQ(algo::LIS(arr), 6); 66 | } 67 | { 68 | std::vector arr{ 1,2,3,4,5,6,7 }; 69 | EXPECT_EQ(algo::LIS(arr), 7); 70 | } 71 | { 72 | std::vector arr{ 9, 7, 5, 3, 2, 1 }; 73 | EXPECT_EQ(algo::LIS(arr), 1); 74 | } 75 | { 76 | std::vector arr{ 1, 2, 1, 6, 1, 8, 1, 9, 77 | 3, 10, 4, 5, 6, 7 }; 78 | EXPECT_EQ(algo::LIS(arr), 7); 79 | } 80 | } 81 | 82 | TEST(LCSTest, FamousProblemsTest) 83 | { 84 | { 85 | std::string str1 = "agcat"; 86 | std::string str2 = "gac"; 87 | EXPECT_EQ( 88 | algo::LCS(str1, str2), 89 | 2 90 | ); 91 | } 92 | { 93 | std::string str1 = "XMJYAUZ"; 94 | std::string str2 = "MZJAWXU"; 95 | EXPECT_EQ( 96 | algo::LCS(str1, str2), 97 | 4 98 | ); 99 | } 100 | { 101 | std::string str1 = "aaaa"; 102 | std::string str2 = "aaaa"; 103 | EXPECT_EQ( 104 | algo::LCS(str1, str2), 105 | 4 106 | ); 107 | } 108 | { 109 | std::string str1 = "abaaa"; 110 | std::string str2 = "abababa"; 111 | EXPECT_EQ( 112 | algo::LCS(str1, str2), 113 | 5 114 | ); 115 | } 116 | 117 | } 118 | TEST(NQueenTest, FamousProblemsTest) 119 | { 120 | std::vector test{ 1, 0, 0, 2, 10, 4, 40, 92, 352, 724 }; 121 | for (int i = 0; i < test.size(); i++) 122 | { 123 | EXPECT_EQ(algo::NQueenProblem(i + 1), test[i]); 124 | } 125 | 126 | 127 | } 128 | 129 | -------------------------------------------------------------------------------- /AlgorithmTest/MathTest.cpp: -------------------------------------------------------------------------------- 1 | #include"pch.h" 2 | 3 | #include"Math/Math.h" 4 | 5 | 6 | 7 | 8 | TEST(BinPowMatrixMulTest, MathTest) 9 | { 10 | 11 | algo::Matrix mat{ {1, 1}, { 1, 0 } }; 12 | algo::Matrix neutral{ {1, 0}, { 0, 1 } }; 13 | algo::Matrix fib{ {1, 1} }; 14 | mat = algo::bin_pow(mat, 7, neutral, algo::matrix_mul); 15 | fib = algo::matrix_mul(fib, mat); 16 | algo::Matrix etalon{ {34, 21} }; 17 | EXPECT_EQ(fib, etalon); 18 | } 19 | TEST(EulerFunctionTest, MathTest) 20 | { 21 | for(int i = 2; i < 1000; ++i) 22 | EXPECT_EQ(algo::euler(i), algo::fast_euler(i)); 23 | } -------------------------------------------------------------------------------- /AlgorithmTest/SortingTest.cpp: -------------------------------------------------------------------------------- 1 | #include"pch.h" 2 | 3 | #include"Sortings/Sorting.h" 4 | 5 | 6 | TEST(SortingTest, SortingTest) 7 | { 8 | auto origin = getRandomVector(6, 0, 9); 9 | auto sorted_origin = origin; 10 | std::sort(sorted_origin.begin(), sorted_origin.end()); 11 | 12 | { 13 | auto copy = origin; 14 | algo::BubbleSort(copy.begin(), copy.end()); 15 | EXPECT_EQ(copy, sorted_origin); 16 | } 17 | { 18 | auto copy = origin; 19 | algo::SelectionSort(copy.begin(), copy.end()); 20 | EXPECT_EQ(copy, sorted_origin); 21 | } 22 | { 23 | auto copy = origin; 24 | algo::InsertionSort(copy.begin(), copy.end()); 25 | EXPECT_EQ(copy, sorted_origin); 26 | } 27 | { 28 | auto copy = origin; 29 | algo::RadixSort(copy.begin(), copy.end()); 30 | EXPECT_EQ(copy, sorted_origin); 31 | } 32 | { 33 | auto copy = origin; 34 | algo::HeapSort(copy.begin(), copy.end()); 35 | EXPECT_EQ(copy, sorted_origin); 36 | } 37 | { 38 | auto copy = origin; 39 | algo::MergeSort(copy.begin(), copy.end()); 40 | EXPECT_EQ(copy, sorted_origin); 41 | } 42 | { 43 | auto copy = origin; 44 | algo::QuickSort(copy.begin(), copy.end()); 45 | EXPECT_EQ(copy, sorted_origin); 46 | } 47 | } -------------------------------------------------------------------------------- /AlgorithmTest/StringTest.cpp: -------------------------------------------------------------------------------- 1 | #include"pch.h" 2 | 3 | #include"Strings/StringHashing.h" 4 | #include"Strings/ZFunction.h" 5 | #include"Strings/PrefixFunction.h" 6 | #include 7 | #include 8 | 9 | TEST(HashingTest, StringTest) 10 | { 11 | { 12 | std::string test_string = "abacaba"; 13 | std::string reverse_string = test_string; 14 | std::reverse(test_string.begin(), test_string.end()); 15 | algo::StringHashing hash1(test_string); 16 | algo::StringHashing hash2(reverse_string); 17 | EXPECT_EQ(hash1.Get(), hash2.Get()); 18 | EXPECT_EQ(hash1.Get(0, 2), hash2.Get(0, 2)); 19 | EXPECT_EQ(hash1.Get(0, 2), hash2.Get(4, 6)); 20 | EXPECT_EQ(hash1.Get(0, 2), hash1.Get(4, 6)); 21 | EXPECT_EQ(hash1.Get(2, 4), hash2.Get(2, 4)); 22 | EXPECT_EQ(hash1.Get(0, 0), 'a'); 23 | EXPECT_EQ(hash1.Get(2, 2), 'a'); 24 | EXPECT_EQ(hash1.Get(4, 4), 'a'); 25 | EXPECT_EQ(hash1.Get(6, 6), 'a'); 26 | } 27 | } 28 | 29 | TEST(PrefixFunctionTest, StringTest) 30 | { 31 | { 32 | algo::PrefixFunction p("abcabcd"); 33 | std::vector etalon{ 0, 0, 0, 1, 2, 3, 0 }; 34 | EXPECT_EQ(p.Get(), etalon); 35 | } 36 | { 37 | algo::PrefixFunction p("aabaaab"); 38 | std::vector etalon{ 0, 1, 0, 1, 2, 2, 3 }; 39 | EXPECT_EQ(p.Get(), etalon); 40 | } 41 | { 42 | algo::PrefixFunction p("abaabaabababaaabbbabababab"); 43 | std::vector etalon{ 0, 0, 1, 1, 2, 3, 4, 44 | 5, 6, 2, 3, 2, 3, 4, 45 | 1, 2, 0, 0, 1, 2, 3, 46 | 2, 3, 2, 3, 2 }; 47 | EXPECT_EQ(p.Get(), etalon); 48 | } 49 | 50 | 51 | } 52 | 53 | TEST(KnuthMorrisPrattTest, StringTest) 54 | { 55 | { 56 | algo::PrefixFunction p("abcabcd"); 57 | std::vector etalon{ 0, 0, 0, 1, 2, 3, 0 }; 58 | EXPECT_EQ(p.Get(), etalon); 59 | } 60 | { 61 | algo::PrefixFunction p("aabaaab"); 62 | std::vector etalon{ 0, 1, 0, 1, 2, 2, 3 }; 63 | EXPECT_EQ(p.Get(), etalon); 64 | } 65 | { 66 | algo::PrefixFunction p("abaabaabababaaabbbababababcd"); 67 | std::vector etalon{ 0, 0, 1, 1, 2, 3, 4, 68 | 5, 6, 2, 3, 2, 3, 4, 69 | 1, 2, 0, 0, 1, 2, 3, 70 | 2, 3, 2, 3, 2, 0, 0 }; 71 | EXPECT_EQ(p.Get(), etalon); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /AlgorithmTest/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /AlgorithmTest/pch.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // pch.cpp 3 | // Include the standard header and generate the precompiled header. 4 | // 5 | 6 | #include "pch.h" 7 | 8 | std::vector getRandomVector(int n, int min, int max) 9 | { 10 | std::vector random_vector(n); 11 | std::mt19937 rand_function(time(0)); 12 | std::uniform_int_distribution uid(min, max); 13 | for (auto& elem : random_vector) 14 | { 15 | elem = uid(rand_function); 16 | } 17 | return random_vector; 18 | } -------------------------------------------------------------------------------- /AlgorithmTest/pch.h: -------------------------------------------------------------------------------- 1 | // 2 | // pch.h 3 | // Header for standard system include files. 4 | // 5 | 6 | #pragma once 7 | 8 | #include "gtest/gtest.h" 9 | #include 10 | #include 11 | #include 12 | 13 | std::vector getRandomVector(int n, int min = -1000, int max = 1000); 14 | 15 | -------------------------------------------------------------------------------- /AlgorithmTest/test.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | TEST(SimpleTestCase, InitialTest) { 4 | EXPECT_EQ(1, 1); 5 | EXPECT_TRUE(true); 6 | } -------------------------------------------------------------------------------- /Algorithms.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Algorithms", "Algorithms\Algorithms.vcxproj", "{8B2C733E-3D87-4AB4-9F08-2DF9102643D7}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06} = {CCB2C8E4-44A5-4731-9556-79CF4A514A06} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodePreprocessor", "CodePreprocessor\CodePreprocessor.vcxproj", "{CCB2C8E4-44A5-4731-9556-79CF4A514A06}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlgorithmTest", "AlgorithmTest\AlgorithmTest.vcxproj", "{BBFFCC52-30D0-4E22-8E51-41245D12E1F1}" 14 | ProjectSection(ProjectDependencies) = postProject 15 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7} = {8B2C733E-3D87-4AB4-9F08-2DF9102643D7} 16 | EndProjectSection 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Coding", "Coding\Coding.vcxproj", "{4BB0180F-DDE9-4172-8518-58FDE5F49D2C}" 19 | ProjectSection(ProjectDependencies) = postProject 20 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7} = {8B2C733E-3D87-4AB4-9F08-2DF9102643D7} 21 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06} = {CCB2C8E4-44A5-4731-9556-79CF4A514A06} 22 | EndProjectSection 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|x64 = Debug|x64 27 | Debug|x86 = Debug|x86 28 | Release|x64 = Release|x64 29 | Release|x86 = Release|x86 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Debug|x64.ActiveCfg = Debug|x64 33 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Debug|x64.Build.0 = Debug|x64 34 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Debug|x86.ActiveCfg = Debug|Win32 35 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Debug|x86.Build.0 = Debug|Win32 36 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Release|x64.ActiveCfg = Release|x64 37 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Release|x64.Build.0 = Release|x64 38 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Release|x86.ActiveCfg = Release|Win32 39 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7}.Release|x86.Build.0 = Release|Win32 40 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Debug|x64.ActiveCfg = Debug|x64 41 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Debug|x64.Build.0 = Debug|x64 42 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Debug|x86.ActiveCfg = Debug|Win32 43 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Debug|x86.Build.0 = Debug|Win32 44 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Release|x64.ActiveCfg = Release|x64 45 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Release|x64.Build.0 = Release|x64 46 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Release|x86.ActiveCfg = Release|Win32 47 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06}.Release|x86.Build.0 = Release|Win32 48 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Debug|x64.ActiveCfg = Debug|x64 49 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Debug|x64.Build.0 = Debug|x64 50 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Debug|x86.ActiveCfg = Debug|Win32 51 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Debug|x86.Build.0 = Debug|Win32 52 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Release|x64.ActiveCfg = Release|x64 53 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Release|x64.Build.0 = Release|x64 54 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Release|x86.ActiveCfg = Release|Win32 55 | {BBFFCC52-30D0-4E22-8E51-41245D12E1F1}.Release|x86.Build.0 = Release|Win32 56 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Debug|x64.ActiveCfg = Debug|x64 57 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Debug|x64.Build.0 = Debug|x64 58 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Debug|x86.ActiveCfg = Debug|Win32 59 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Debug|x86.Build.0 = Debug|Win32 60 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Release|x64.ActiveCfg = Release|x64 61 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Release|x64.Build.0 = Release|x64 62 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Release|x86.ActiveCfg = Release|Win32 63 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C}.Release|x86.Build.0 = Release|Win32 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | GlobalSection(ExtensibilityGlobals) = postSolution 69 | SolutionGuid = {A0DA8114-FBE4-4597-A8BD-1CE3034D4D47} 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /Algorithms/Algorithms.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {8B2C733E-3D87-4AB4-9F08-2DF9102643D7} 24 | Win32Proj 25 | Algorithms 26 | 10.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | StaticLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | $(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 76 | 77 | 78 | true 79 | 80 | 81 | false 82 | $(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 83 | 84 | 85 | false 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | ./include 94 | false 95 | 96 | 97 | true 98 | Console 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | Level3 108 | Disabled 109 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 110 | true 111 | ./include 112 | false 113 | 114 | 115 | true 116 | Console 117 | 118 | 119 | 120 | 121 | 122 | 123 | lib /NOLOGO /OUT:"$(TargetPath).lib" "$(ProjectDir)/$(Configuration)*.obj" 124 | 125 | 126 | 127 | 128 | Level3 129 | MaxSpeed 130 | true 131 | true 132 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | ./include 135 | false 136 | 137 | 138 | true 139 | true 140 | true 141 | Console 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | Level3 151 | MaxSpeed 152 | true 153 | true 154 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 155 | true 156 | false 157 | ./include 158 | 159 | 160 | true 161 | true 162 | true 163 | Console 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /Algorithms/Algorithms.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {3ab02b56-21e7-4e57-b6e6-e0b5c50e1235} 18 | 19 | 20 | {b9bca163-90bc-4778-86af-ed7d6f16ee10} 21 | 22 | 23 | {2d803e43-0b94-49f5-9070-3f0233e02202} 24 | 25 | 26 | {a56662c6-f0fd-40ef-be10-f2f8276a61c4} 27 | 28 | 29 | {26bd53f2-f27e-4f28-8c12-8eb2895d5ee9} 30 | 31 | 32 | {e4694ef6-26a2-475b-befe-ccf2482c60b3} 33 | 34 | 35 | {3aada30b-67a2-469a-b866-cf6051875bdc} 36 | 37 | 38 | {28d2e31f-8a66-4db7-ae33-b46ac0a0ea1f} 39 | 40 | 41 | {212c4917-20db-4815-afa0-9a6027dee045} 42 | 43 | 44 | {00eb6170-afbd-4ac7-8481-b31e2e3fdbe1} 45 | 46 | 47 | {7ea4070e-cb4e-4b86-abc7-68314d48219b} 48 | 49 | 50 | {038c953c-6005-46ad-825c-4a515293a857} 51 | 52 | 53 | {1f5fa0f2-d9ec-4ffe-8f7a-a491e8ea67e7} 54 | 55 | 56 | 57 | 58 | Header Files\Utils 59 | 60 | 61 | Header Files\Utils 62 | 63 | 64 | Header Files\Utils 65 | 66 | 67 | Header Files\Graph 68 | 69 | 70 | Header Files\Graph 71 | 72 | 73 | Header Files\Graph 74 | 75 | 76 | Header Files\Graph 77 | 78 | 79 | Header Files\Geometry 80 | 81 | 82 | Header Files\Graph 83 | 84 | 85 | Header Files\Graph 86 | 87 | 88 | Header Files\Graph 89 | 90 | 91 | Header Files\Graph 92 | 93 | 94 | Header Files\Graph 95 | 96 | 97 | Header Files\Graph 98 | 99 | 100 | Header Files\Sortings 101 | 102 | 103 | Header Files\DataStructures 104 | 105 | 106 | Header Files\Graph 107 | 108 | 109 | Header Files\Graph 110 | 111 | 112 | Header Files\Graph 113 | 114 | 115 | Header Files\Graph 116 | 117 | 118 | Header Files\Graph 119 | 120 | 121 | Header Files\DataStructures 122 | 123 | 124 | Header Files\Graph 125 | 126 | 127 | Header Files\Graph 128 | 129 | 130 | Header Files\FamousProblems 131 | 132 | 133 | Header Files\DataStructures 134 | 135 | 136 | Header Files\Math 137 | 138 | 139 | Header Files\Strings 140 | 141 | 142 | Header Files\DataStructures 143 | 144 | 145 | Header Files\DataStructures 146 | 147 | 148 | Header Files\FamousProblems 149 | 150 | 151 | Header Files\Strings 152 | 153 | 154 | Header Files\Strings 155 | 156 | 157 | Header Files\Strings 158 | 159 | 160 | Header Files\DataStructures 161 | 162 | 163 | 164 | 165 | Resource Files\Geometry 166 | 167 | 168 | Resource Files\Graph 169 | 170 | 171 | Resource Files\Graph 172 | 173 | 174 | Resource Files\Graph 175 | 176 | 177 | Resource Files\Graph 178 | 179 | 180 | Resource Files\Graph 181 | 182 | 183 | Resource Files\Graph 184 | 185 | 186 | Resource Files\Graph 187 | 188 | 189 | Resource Files\Graph 190 | 191 | 192 | Resource Files\Graph 193 | 194 | 195 | Resource Files\Graph 196 | 197 | 198 | Resource Files\Graph 199 | 200 | 201 | Resource Files\Graph 202 | 203 | 204 | Resource Files\Graph 205 | 206 | 207 | Resource Files\Graph 208 | 209 | 210 | Resource Files\Graph 211 | 212 | 213 | Resource Files\DataStructures 214 | 215 | 216 | Resource Files\Graph 217 | 218 | 219 | Resource Files\Graph 220 | 221 | 222 | Resource Files\Strings 223 | 224 | 225 | Resource Files\Strings 226 | 227 | 228 | Resource Files\Strings 229 | 230 | 231 | Resource Files\Strings 232 | 233 | 234 | Header Files 235 | 236 | 237 | -------------------------------------------------------------------------------- /Algorithms/Source_processed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #pragma once 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace algo 13 | { 14 | const int Inf = INT_MAX; 15 | const long long LInf = LLONG_MAX; 16 | 17 | template 18 | T max(T first, Others... others); 19 | 20 | template 21 | T max(T first); 22 | 23 | template 24 | T min(T first, Others... others); 25 | 26 | template 27 | T min(T first); 28 | 29 | template 30 | void input_container(std::istream& in, 31 | int& n, 32 | Container& container); 33 | 34 | template 35 | void output_container(std::ostream& out, 36 | const Container& container, 37 | const std::string& delimiter = " "); 38 | 39 | template 40 | void sum_container(const Container& container, T& sum); 41 | 42 | 43 | template 44 | using Matrix = std::vector>; 45 | 46 | template 47 | Matrix createMatrix(size_t n, size_t m, T etalon = T()); 48 | 49 | double random(double min, double max); 50 | } 51 | 52 | #pragma once 53 | #include 54 | #include 55 | namespace algo 56 | { 57 | template 58 | inline T max(T first, Others... others) 59 | { 60 | return std::max(first, max(others...)); 61 | } 62 | template 63 | inline T max(T first) 64 | { 65 | return first; 66 | } 67 | 68 | template 69 | inline T min(T first, Others... others) 70 | { 71 | return std::min(first, min(others...)); 72 | } 73 | template 74 | inline T min(T first) 75 | { 76 | return first; 77 | } 78 | 79 | template 80 | inline void sum_container(const Container& container, T& sum) 81 | { 82 | for (auto& elem : container) 83 | { 84 | sum += elem; 85 | } 86 | } 87 | 88 | template 89 | inline Matrix createMatrix(size_t n, size_t m, T etalon) 90 | { 91 | return Matrix(n, std::vector(m, etalon)); 92 | } 93 | 94 | inline double random(double min, double max) 95 | { 96 | std::random_device rd; 97 | std::mt19937 mt(rd()); 98 | std::uniform_real_distribution dist(min, max); 99 | return dist(mt); 100 | } 101 | 102 | template 103 | inline void input_container(std::istream& in, 104 | int& n, 105 | Container& container) 106 | { 107 | in >> n; 108 | container.resize(n); 109 | for (auto& elem : container) 110 | { 111 | in >> elem; 112 | } 113 | } 114 | 115 | template 116 | inline void output_container(std::ostream& out, 117 | const Container& container, 118 | const std::string& delimiter) 119 | { 120 | for (auto& elem : container) 121 | { 122 | out << elem << delimiter; 123 | } 124 | } 125 | } 126 | 127 | 128 | 129 | 130 | 131 | #pragma once 132 | 133 | 134 | namespace algo 135 | { 136 | 137 | #define in_vec(in, n, c, t) \ 138 | int n; \ 139 | std::vector c; \ 140 | algo::input_container(in, n, c) 141 | 142 | #define cin_vec(n, c, t) \ 143 | in_vec(std::cin, n, c, t) 144 | 145 | #define in_vec_int(in, n, c) \ 146 | in_vec(in, n, c, int) 147 | 148 | #define cin_vec_int(n, c) \ 149 | cin_vec(n, c, int) 150 | 151 | #define out_vec_delim(out, c, d) \ 152 | algo::output_container(out, c, d) 153 | 154 | #define out_vec(out, c) \ 155 | algo::output_container(out, c) 156 | 157 | #define cout_vec_delim(c, d) \ 158 | algo::output_container(std::cout, c, d) 159 | 160 | #define cout_vec(c, d) \ 161 | algo::output_container(std::cout, c) 162 | 163 | #define sum_vec(c, s, t) \ 164 | t s = 0; \ 165 | algo::sum_container(c, s) 166 | 167 | #define all(v) v.begin(), v.end() 168 | #define rall(v) v.rbegin(), v.rend() 169 | 170 | } 171 | 172 | 173 | int main() 174 | { 175 | 176 | } 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/FenwickTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | template 7 | class FenwickTree 8 | { 9 | public: 10 | private: 11 | std::vector m_vec; 12 | std::vector m_tree; 13 | 14 | T query(int to) const; 15 | public: 16 | FenwickTree(const std::vector& vec); 17 | 18 | void build_tree(); 19 | void update(int pos, T elem); 20 | T query(int from, int to) const; 21 | int size() const; 22 | }; 23 | } 24 | 25 | 26 | namespace algo 27 | { 28 | template 29 | inline FenwickTree::FenwickTree(const std::vector& vec) 30 | : m_vec(vec) 31 | , m_tree(m_vec.size()) 32 | { 33 | } 34 | template 35 | inline void algo::FenwickTree::build_tree() 36 | { 37 | for (int i = 0; i < m_vec.size(); ++i) 38 | { 39 | update(i, m_vec[i]); 40 | } 41 | } 42 | template 43 | inline void FenwickTree::update(int pos, T elem) 44 | { 45 | for (; pos < m_vec.size(); pos |= pos + 1) 46 | { 47 | m_tree[pos] += elem; 48 | } 49 | } 50 | template 51 | inline T FenwickTree::query(int to) const 52 | { 53 | int sum = 0; 54 | for (; to >= 0; to = (to & (to + 1)) - 1) 55 | { 56 | sum += m_tree[to]; 57 | } 58 | return sum; 59 | } 60 | template 61 | inline T FenwickTree::query(int from, int to) const 62 | { 63 | return query(to) - query(from - 1); 64 | } 65 | template 66 | inline int FenwickTree::size() const 67 | { 68 | return m_vec.size(); 69 | } 70 | } 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/LazySegmentTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | namespace algo 6 | { 7 | template 8 | class LazySegmentTree 9 | { 10 | public: 11 | static T min(T a, T b) 12 | { 13 | return a < b ? a : b; 14 | } 15 | static T max(T a, T b) 16 | { 17 | return a > b ? a : b; 18 | } 19 | static T sum(T a, T b) 20 | { 21 | return a + b; 22 | } 23 | enum class UpdateType 24 | { 25 | Assign, 26 | Sum, 27 | Product 28 | }; 29 | private: 30 | std::vector m_vec; 31 | std::vector m_tree; 32 | std::vector m_lazy_prop; 33 | std::function m_tree_logic; 34 | T m_neutral_element; 35 | UpdateType m_upd_type; 36 | 37 | void build_tree(int v, int l, int r); 38 | void update(int pos, T elem, int v, int l, int r); 39 | void update(int pos_l, int pos_r, T elem, int v, int l, int r); 40 | T query(int from, int to, int v, int l, int r); 41 | static int left(int v); 42 | static int right(int v); 43 | static int mid(int l, int r); 44 | void update_one(T& a, T b); 45 | T update_many(int v, int l, int r); 46 | public: 47 | LazySegmentTree(const std::vector& vec, 48 | const std::function& tree_logic, 49 | T neutral_element, 50 | UpdateType upd_type = UpdateType::Assign); 51 | 52 | void build_tree(); 53 | void update(int pos, T elem); 54 | void update(int pos_l, int pos_r, T elem); 55 | T query(int from, int to); 56 | T query(int pos); 57 | int size() const; 58 | private: 59 | void push(int v) 60 | { 61 | if (m_lazy_prop[v] != m_neutral_element) { 62 | if (m_lazy_prop[left(v)] == m_neutral_element) 63 | m_lazy_prop[left(v)] = m_lazy_prop[v]; 64 | else 65 | update_one(m_lazy_prop[left(v)], m_lazy_prop[v]); 66 | 67 | if (m_lazy_prop[right(v)] == m_neutral_element) 68 | m_lazy_prop[right(v)] = m_lazy_prop[v]; 69 | else 70 | update_one(m_lazy_prop[right(v)], m_lazy_prop[v]); 71 | m_lazy_prop[v] = m_neutral_element; 72 | } 73 | } 74 | }; 75 | } 76 | 77 | 78 | namespace algo 79 | { 80 | template 81 | inline void LazySegmentTree::build_tree(int v, int l, int r) 82 | { 83 | if (l == r) 84 | { 85 | m_tree[v] = m_vec[l]; 86 | } 87 | else 88 | { 89 | int m = mid(l, r); 90 | build_tree(left(v), l, m); 91 | build_tree(right(v), m + 1, r); 92 | m_tree[v] = m_tree_logic(m_tree[left(v)], m_tree[right(v)]); 93 | } 94 | } 95 | 96 | template 97 | inline void LazySegmentTree::update(int pos, T elem, int v, int l, int r) 98 | { 99 | if (l == r) 100 | { 101 | update_one(m_tree[v], elem); 102 | update_one(m_vec[pos], elem); 103 | } 104 | else 105 | { 106 | push(v); 107 | int m = mid(l, r); 108 | if (pos <= m) 109 | { 110 | update(pos, elem, left(v), l, m); 111 | } 112 | else 113 | { 114 | update(pos, elem, right(v), m + 1, r); 115 | } 116 | m_tree[v] = m_tree_logic(m_tree[left(v)], m_tree[right(v)]); 117 | } 118 | } 119 | 120 | template 121 | inline void LazySegmentTree::update(int pos_l, int pos_r, T elem, int v, int l, int r) 122 | { 123 | if (pos_l > pos_r) 124 | { 125 | return; 126 | } 127 | if (pos_l == l && pos_r == r) 128 | { 129 | if (m_lazy_prop[v] == m_neutral_element) 130 | m_lazy_prop[v] = elem; 131 | else 132 | update_one(m_lazy_prop[v], elem); 133 | } 134 | else 135 | { 136 | push(v); 137 | int m = mid(l, r); 138 | update(pos_l, min(pos_r, m), elem, left(v), l, m); 139 | update(max(pos_l, m + 1), pos_r, elem, right(v), m + 1, r); 140 | T left_ans = update_many(left(v), l, m); 141 | T right_ans = update_many(right(v), m + 1, r); 142 | m_tree[v] = m_tree_logic(left_ans, right_ans); 143 | } 144 | } 145 | 146 | template 147 | inline T LazySegmentTree::query(int from, int to, int v, int l, int r) 148 | { 149 | if (from > to) 150 | { 151 | return m_neutral_element; 152 | } 153 | if (from == l && to == r) 154 | { 155 | if (m_lazy_prop[v] == m_neutral_element) 156 | return m_tree[v]; 157 | return m_tree[v] + m_lazy_prop[v]; 158 | } 159 | else 160 | { 161 | push(v); 162 | int m = mid(l, r); 163 | T left_ans = query(from, std::min(m, to), left(v), l, m); 164 | T right_ans = query(std::max(from, m+1), to, right(v), m + 1, r); 165 | m_tree[v] = m_tree_logic(update_many(left(v), l, m), 166 | update_many(right(v), m + 1, r)); 167 | return m_tree_logic(m_tree_logic(left_ans, right_ans), m_lazy_prop[v]); 168 | } 169 | } 170 | 171 | template 172 | inline int LazySegmentTree::left(int v) 173 | { 174 | return v << 1; 175 | } 176 | 177 | template 178 | inline int LazySegmentTree::right(int v) 179 | { 180 | return (v << 1) + 1; 181 | } 182 | 183 | template 184 | inline int LazySegmentTree::mid(int l, int r) 185 | { 186 | return (l + r) >> 1; 187 | } 188 | 189 | template 190 | inline void LazySegmentTree::update_one(T& a, T b) 191 | { 192 | switch (m_upd_type) 193 | { 194 | case UpdateType::Assign: 195 | a = b; 196 | break; 197 | case UpdateType::Sum: 198 | a += b; 199 | break; 200 | case UpdateType::Product: 201 | a *= b; 202 | break; 203 | default: 204 | break; 205 | } 206 | } 207 | template 208 | inline T LazySegmentTree::update_many(int v, int l, int r) 209 | { 210 | return m_tree[v] + m_lazy_prop[v]; 211 | /*T ans = m_tree[v] + m_lazy_prop[v]; 212 | if (m_lazy_prop[v] != m_neutral_element) 213 | { 214 | if (m_upd_type == UpdateType::Assign) 215 | { 216 | update_one(ans, m_lazy_prop[v]); 217 | } 218 | else if (m_upd_type == UpdateType::Sum) 219 | { 220 | update_one(ans, m_lazy_prop[v] * (r - l + 1)); 221 | } 222 | else if (m_upd_type == UpdateType::Product) 223 | { 224 | update_one(ans, bin_pow(m_lazy_prop[v], r - l + 1)); 225 | } 226 | } 227 | return ans;*/ 228 | } 229 | 230 | template 231 | LazySegmentTree::LazySegmentTree(const std::vector& vec, 232 | const std::function& tree_logic, 233 | T neutral_element, 234 | UpdateType upd_type) 235 | : m_vec(vec) 236 | , m_tree_logic(tree_logic) 237 | , m_neutral_element(neutral_element) 238 | , m_upd_type(upd_type) 239 | { 240 | m_tree.resize(m_vec.size() << 2); 241 | m_lazy_prop.resize(m_tree.size(), m_neutral_element); 242 | build_tree(); 243 | } 244 | 245 | template 246 | inline void LazySegmentTree::build_tree() 247 | { 248 | build_tree(1, 0, m_vec.size() - 1); 249 | } 250 | 251 | template 252 | inline void LazySegmentTree::update(int pos, T elem) 253 | { 254 | update(pos, elem, 1, 0, m_vec.size() - 1); 255 | } 256 | 257 | template 258 | inline void LazySegmentTree::update(int pos_l, int pos_r, T elem) 259 | { 260 | return update(pos_l, pos_r, elem, 1, 0, m_vec.size() - 1); 261 | } 262 | 263 | template 264 | inline T LazySegmentTree::query(int from, int to) 265 | { 266 | return query(from, to, 1, 0, m_vec.size() - 1); 267 | } 268 | 269 | template 270 | inline T LazySegmentTree::query(int pos) 271 | { 272 | return query(pos, pos, 1, 0, m_vec.size() - 1); 273 | } 274 | 275 | template 276 | inline int LazySegmentTree::size() const 277 | { 278 | return m_vec.size(); 279 | } 280 | } 281 | 282 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/RedBlackTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace algo 4 | { 5 | template 6 | class RBTree 7 | { 8 | struct Node 9 | { 10 | Node* left; 11 | Node* right; 12 | Node* father; 13 | T value; 14 | bool red; 15 | Node(T value, bool red, Node* left = nullptr, 16 | Node* right = nullptr, 17 | Node* father = nullptr) 18 | : value(value) 19 | , red(red) 20 | , left(left) 21 | , right(right) 22 | , father(father) 23 | { 24 | 25 | } 26 | }; 27 | Node* m_root; 28 | 29 | void fix_insertion(Node* root); 30 | public: 31 | RBTree(); 32 | void insert(const T& value); 33 | void erase(const T& value); 34 | }; 35 | } 36 | 37 | 38 | namespace algo 39 | { 40 | template 41 | inline void RBTree::fix_insertion(Node* temp) 42 | { 43 | if (temp == m_root) 44 | { 45 | temp->red = false; 46 | return; 47 | } 48 | while (temp->parent->red) 49 | { 50 | if (temp->parent->parent->left == temp->parent) 51 | { 52 | if (temp->parent->parent->right) 53 | { 54 | if (temp->parent->parent->right->red) 55 | { 56 | temp->parent->red = false; 57 | temp->parent->parent->right->red = false; 58 | temp->parent->parent->red = true; 59 | temp = temp->parent->parent; 60 | } 61 | } 62 | else // if (!temp->parent->parent->right) 63 | { 64 | // TODO 65 | } 66 | } 67 | } 68 | } 69 | template 70 | RBTree::RBTree() 71 | : m_root(nullptr) 72 | { 73 | 74 | } 75 | 76 | template 77 | inline void RBTree::insert(const T& value) 78 | { 79 | Node* temp(value, true); 80 | if (root == nullptr) 81 | { 82 | root = temp; 83 | } 84 | else 85 | { 86 | Node* p = m_root; 87 | Node* q = nullptr; 88 | while (p != nullptr) 89 | { 90 | q = p; 91 | if (p->value > temp.value) 92 | { 93 | p = p->left; 94 | } 95 | else 96 | { 97 | p = p->right; 98 | } 99 | } 100 | temp.parent = q; 101 | if (q.value > temp.value) 102 | { 103 | q->left = temp; 104 | } 105 | else 106 | { 107 | q->right = temp; 108 | } 109 | fix_insertion(temp); 110 | } 111 | } 112 | 113 | template 114 | inline void RBTree::erase(const T& value) 115 | { 116 | } 117 | 118 | } -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/SegmentTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | template 7 | class SegmentTree 8 | { 9 | public: 10 | static T min(T a, T b) 11 | { 12 | return a < b ? a : b; 13 | } 14 | static T max(T a, T b) 15 | { 16 | return a > b ? a : b; 17 | } 18 | static T sum(T a, T b) 19 | { 20 | return a + b; 21 | } 22 | enum class UpdateType 23 | { 24 | Assign, 25 | Sum, 26 | Product 27 | }; 28 | private: 29 | std::vector m_vec; 30 | std::vector m_tree; 31 | std::function m_tree_logic; 32 | T m_neutral_element; 33 | UpdateType m_upd_type; 34 | 35 | void build_tree(int v, int l, int r); 36 | void update(int pos, T elem, int v, int l, int r); 37 | T query(int from, int to, int v, int l, int r) const; 38 | static int left(int v); 39 | static int right(int v); 40 | static int mid(int l, int r); 41 | void update_one(T& a, T b); 42 | public: 43 | SegmentTree(const std::vector& vec, 44 | const std::function& tree_logic, 45 | T neutral_element, 46 | UpdateType upd_type = UpdateType::Assign); 47 | 48 | void build_tree(); 49 | void update(int pos, T elem); 50 | T query(int from, int to) const; 51 | T query(int pos) const; 52 | int size() const; 53 | }; 54 | } 55 | 56 | 57 | namespace algo 58 | { 59 | template 60 | inline void SegmentTree::build_tree(int v, int l, int r) 61 | { 62 | if (l == r) 63 | { 64 | m_tree[v] = m_vec[l]; 65 | } 66 | else 67 | { 68 | int m = mid(l, r); 69 | build_tree(left(v), l, m); 70 | build_tree(right(v), m + 1, r); 71 | m_tree[v] = m_tree_logic(m_tree[left(v)], m_tree[right(v)]); 72 | } 73 | } 74 | 75 | template 76 | inline void SegmentTree::update(int pos, T elem, int v, int l, int r) 77 | { 78 | if (l == r) 79 | { 80 | update_one(m_tree[v], elem); 81 | update_one(m_vec[pos], elem); 82 | } 83 | else 84 | { 85 | int m = mid(l, r); 86 | if (pos <= m) 87 | { 88 | update(pos, elem, left(v), l, m); 89 | } 90 | else 91 | { 92 | update(pos, elem, right(v), m + 1, r); 93 | } 94 | m_tree[v] = m_tree_logic(m_tree[left(v)], m_tree[right(v)]); 95 | } 96 | } 97 | 98 | template 99 | inline T SegmentTree::query(int from, int to, int v, int l, int r) const 100 | { 101 | if (from > to) 102 | { 103 | return m_neutral_element; 104 | } 105 | if (from == l && to == r) 106 | { 107 | return m_tree[v]; 108 | } 109 | else 110 | { 111 | int m = mid(l, r); 112 | T left_ans = query(from, std::min(m, to), left(v), l, m); 113 | T right_ans = query(std::max(from, m+1), to, right(v), m + 1, r); 114 | return m_tree_logic(left_ans, right_ans); 115 | } 116 | } 117 | 118 | template 119 | inline int SegmentTree::left(int v) 120 | { 121 | return v << 1; 122 | } 123 | 124 | template 125 | inline int SegmentTree::right(int v) 126 | { 127 | return (v << 1) + 1; 128 | } 129 | 130 | template 131 | inline int SegmentTree::mid(int l, int r) 132 | { 133 | return (l + r) >> 1; 134 | } 135 | 136 | template 137 | inline void SegmentTree::update_one(T& a, T b) 138 | { 139 | switch (m_upd_type) 140 | { 141 | case UpdateType::Assign: 142 | a = b; 143 | break; 144 | case UpdateType::Sum: 145 | a += b; 146 | break; 147 | case UpdateType::Product: 148 | a *= b; 149 | break; 150 | default: 151 | break; 152 | } 153 | } 154 | 155 | template 156 | SegmentTree::SegmentTree(const std::vector& vec, 157 | const std::function& tree_logic, 158 | T neutral_element, 159 | UpdateType upd_type) 160 | : m_vec(vec) 161 | , m_tree_logic(tree_logic) 162 | , m_neutral_element(neutral_element) 163 | , m_upd_type(upd_type) 164 | { 165 | if (m_vec.size() == 0) 166 | return; 167 | m_tree.resize(m_vec.size() << 2); 168 | build_tree(); 169 | } 170 | 171 | template 172 | inline void SegmentTree::build_tree() 173 | { 174 | build_tree(1, 0, m_vec.size() - 1); 175 | } 176 | 177 | template 178 | inline void SegmentTree::update(int pos, T elem) 179 | { 180 | update(pos, elem, 1, 0, m_vec.size() - 1); 181 | } 182 | 183 | template 184 | inline T SegmentTree::query(int from, int to) const 185 | { 186 | return query(from, to, 1, 0, m_vec.size() - 1); 187 | } 188 | 189 | template 190 | inline T SegmentTree::query(int pos) const 191 | { 192 | return query(pos, pos, 1, 0, m_vec.size() - 1); 193 | } 194 | 195 | template 196 | inline int SegmentTree::size() const 197 | { 198 | return m_vec.size(); 199 | } 200 | } 201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/SkipList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace algo 9 | { 10 | class SkipList 11 | { 12 | struct Node; 13 | struct Link 14 | { 15 | Node* next; 16 | int skip; 17 | }; 18 | struct Node 19 | { 20 | std::vector links; 21 | int val; 22 | }; 23 | 24 | std::vector nodes; 25 | int size; 26 | std::random_device rd; 27 | std::mt19937 mt; 28 | std::uniform_int_distribution rnd; 29 | 30 | int randomHeight() 31 | { 32 | int l = 0; 33 | for (auto a = rnd(mt); a & 1; a >>= 1) 34 | l++; 35 | return l; 36 | } 37 | 38 | public: 39 | SkipList() 40 | { 41 | size = 1; 42 | nodes.resize(10001); 43 | mt = std::mt19937(rd()); 44 | rnd = std::uniform_int_distribution(0, 0xFFFF); 45 | } 46 | 47 | void insert(int val) 48 | { 49 | struct StackEntry 50 | { 51 | Link* link; 52 | int pos; 53 | }; 54 | std::stack s; 55 | 56 | Node* curNode = &nodes[0], * newNode = &nodes[size++]; 57 | int addH = randomHeight(), pos = 0; 58 | int off = 1 + addH - (int)curNode->links.size(); 59 | curNode->links.reserve(std::max(curNode->links.size(), curNode->links.size() + off)); 60 | newNode->val = val; 61 | 62 | while (off-- > 0) 63 | curNode->links.push_back({ 0, 0 }); 64 | int curH = nodes[0].links.size() - 1; 65 | while (curH >= 0) 66 | { 67 | auto nextNode = curNode->links[curH].next; 68 | if (!nextNode || nextNode->val > val) 69 | { 70 | if (addH >= curH) 71 | s.push({ &curNode->links[curH], pos }); 72 | else 73 | curNode->links[curH].skip++; 74 | curH--; 75 | } 76 | else 77 | { 78 | pos += curNode->links[curH].skip; 79 | curNode = nextNode; 80 | } 81 | } 82 | 83 | while (!s.empty()) 84 | { 85 | auto entry = s.top(); 86 | s.pop(); 87 | newNode->links.push_back({ entry.link->next, entry.link->skip + entry.pos - pos }); 88 | entry.link->next = newNode; 89 | entry.link->skip = 1 + pos - entry.pos; 90 | } 91 | } 92 | 93 | int search(int val) 94 | { 95 | Node* curNode = &nodes[0]; 96 | int curH = curNode->links.size() - 1; 97 | int pos = 0; 98 | 99 | while (curH >= 0) 100 | { 101 | auto nextNode = curNode->links[curH].next; 102 | if (pos + val + curNode->links[curH].skip <= 103 | (nextNode ? nextNode->val : std::numeric_limits::max())) 104 | curH--; 105 | else 106 | { 107 | pos += curNode->links[curH].skip; 108 | curNode = nextNode; 109 | } 110 | } 111 | return val + pos; 112 | } 113 | }; 114 | } 115 | -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/SparseTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace algo 6 | { 7 | template 8 | class SparseTable 9 | { 10 | std::vector m_arr; 11 | std::vector m_logs; 12 | std::vector> m_table; 13 | 14 | 15 | void compute_logs(); 16 | void build_sparse_table(); 17 | public: 18 | SparseTable(const std::vector& arr); 19 | T query(int a, int b) const; 20 | }; 21 | } 22 | 23 | 24 | 25 | 26 | namespace algo 27 | { 28 | template 29 | inline void SparseTable::compute_logs() 30 | { 31 | m_logs[1] = 0; 32 | for (int i = 2; i < m_logs.size(); ++i) 33 | { 34 | m_logs[i] = m_logs[i >> 1] + 1; 35 | } 36 | } 37 | template 38 | inline void SparseTable::build_sparse_table() 39 | { 40 | m_table[0] = m_arr; 41 | 42 | for (int i = 1; i <= m_logs[m_arr.size()]; ++i) 43 | { 44 | int cur_length = 1 << i; 45 | for (int j = 0; j + cur_length <= m_arr.size(); ++j) 46 | { 47 | m_table[i][j] = std::min(m_table[i - 1][j], 48 | m_table[i - 1][j + (cur_length >> 1)]); 49 | } 50 | } 51 | } 52 | template 53 | inline SparseTable::SparseTable(const std::vector& arr) 54 | : m_arr(arr) 55 | , m_logs(arr.size() + 1) 56 | , m_table(log2(arr.size()) + 1, std::vector(arr.size())) 57 | { 58 | compute_logs(); 59 | build_sparse_table(); 60 | } 61 | template 62 | inline T SparseTable::query(int l, int r) const 63 | { 64 | int lo = m_logs[r - l + 1]; 65 | return std::min(m_table[lo][l], m_table[lo][r - (1 << lo) + 1]); 66 | } 67 | } -------------------------------------------------------------------------------- /Algorithms/include/DataStructures/Trie.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | // add Trie for any kind of symbol 7 | // currently only lowercase letters are supported 8 | class Trie 9 | {/* 10 | public: 11 | enum class TrieType 12 | { 13 | LowerLetters = 1, 14 | UpperLetters = 2, 15 | Digits = 4, 16 | Other = 8 17 | };*/ 18 | private: 19 | 20 | struct Node 21 | { 22 | std::vector alphabet; 23 | bool word_end; 24 | Node(); 25 | }; 26 | static int index_of_char(char ch); 27 | void add_word(Node*& curr_node, const std::string& word, int index); 28 | bool find_word(Node* const& curr_node, 29 | const std::string& word, 30 | int index) const; 31 | 32 | //TrieType m_type; 33 | static const int AlphabetSize = 26; 34 | Node* m_root; 35 | 36 | public: 37 | 38 | Trie(); 39 | //Trie(TrieType type = TrieType::LowerLetters); 40 | void add_word(const std::string& word); 41 | bool find_word(const std::string& word) const; 42 | }; 43 | } -------------------------------------------------------------------------------- /Algorithms/include/Defines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include"Utils.h" 4 | 5 | namespace algo 6 | { 7 | 8 | #define in_vec(in, n, c, t) \ 9 | int n; \ 10 | std::vector c; \ 11 | algo::input_container(in, n, c) 12 | 13 | #define cin_vec(n, c, t) \ 14 | in_vec(std::cin, n, c, t) 15 | 16 | #define in_vec_int(in, n, c) \ 17 | in_vec(in, n, c, int) 18 | 19 | #define cin_vec_int(n, c) \ 20 | cin_vec(n, c, int) 21 | 22 | #define out_vec_delim(out, c, d) \ 23 | algo::output_container(out, c, d) 24 | 25 | #define out_vec(out, c) \ 26 | algo::output_container(out, c) 27 | 28 | #define cout_vec_delim(c, d) \ 29 | algo::output_container(std::cout, c, d) 30 | 31 | #define cout_vec(c, d) \ 32 | algo::output_container(std::cout, c) 33 | 34 | #define sum_vec(c, s, t) \ 35 | t s = 0; \ 36 | algo::sum_container(c, s) 37 | 38 | #define all(v) v.begin(), v.end() 39 | #define so(v) std::sort(all(v)) 40 | #define rall(v) v.rbegin(), v.rend() 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Algorithms/include/FamousProblems/AllProblems.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace algo 10 | { 11 | template 12 | int LIS(const T& seq); 13 | template 14 | int LCS(const T& seq1, const T& seq2); 15 | template 16 | int Livenshtein(const T& seq1, const T& seq2); 17 | 18 | using MatrixSize = std::pair; 19 | using MatricesSize = std::vector; 20 | int MatrixMultProblem(const MatricesSize& sizes); 21 | int NQueenProblem(int n); 22 | } 23 | 24 | 25 | 26 | namespace algo 27 | { 28 | template 29 | int LIS(const T& seq) 30 | { 31 | std::vector dp(seq.size() + 1, Inf); 32 | dp[0] = -Inf; 33 | for (int i = 0; i < seq.size(); ++i) 34 | { 35 | int j = std::upper_bound(all(dp), seq[i]) - dp.begin(); 36 | if (dp[j - 1] < seq[i] && seq[i] < dp[j]) 37 | { 38 | dp[j] = seq[i]; 39 | } 40 | } 41 | int ans = 0; 42 | for (int i = 0; i < dp.size(); ++i) 43 | { 44 | if (dp[i] < Inf) 45 | { 46 | ans = i; 47 | } 48 | } 49 | return ans; 50 | } 51 | template 52 | int LCS(const T& seq1, const T& seq2) 53 | { 54 | std::vector> dp(seq1.size() + 1, 55 | std::vector(seq2.size() + 1, Inf)); 56 | for (int i = 0; i <= seq1.size(); ++i) 57 | { 58 | dp[i][0] = 0; 59 | } 60 | for (int i = 0; i <= seq2.size(); ++i) 61 | { 62 | dp[0][i] = 0; 63 | } 64 | for (int i = 1; i <= seq1.size(); ++i) 65 | { 66 | for (int j = 1; j <= seq2.size(); ++j) 67 | { 68 | if (seq1[i - 1] == seq2[j - 1]) 69 | { 70 | dp[i][j] = dp[i - 1][j - 1] + 1; 71 | } 72 | else 73 | { 74 | dp[i][j] = std::max(dp[i][j - 1], dp[i - 1][j]); 75 | } 76 | } 77 | } 78 | return dp[seq1.size()][seq2.size()]; 79 | } 80 | template 81 | int Livenshtein(const T& seq1, const T& seq2) 82 | { 83 | std::vector> dist(seq1.size() + 1, 84 | std::vector(seq2.size() + 1, Inf)); 85 | dist[0][0] = 0; 86 | for (int i = 0; i < seq1.size(); ++i) 87 | { 88 | dist[i + 1][0] = dist[i][0] + 1; 89 | } 90 | for (int i = 0; i < seq2.size(); ++i) 91 | { 92 | dist[0][i + 1] = dist[0][i] + 1; 93 | } 94 | for (int i = 1; i <= seq1.size(); ++i) 95 | { 96 | for (int j = 1; j <= seq2.size(); ++j) 97 | { 98 | dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1); 99 | dist[i][j] = min(dist[i][j], dist[i][j - 1] + 1); 100 | bool same_letter = seq1[i - 1] != seq2[j - 1]; 101 | dist[i][j] = min(dist[i][j], dist[i - 1][j - 1] + same_letter); 102 | } 103 | } 104 | return dist[seq1.size()][seq2.size()]; 105 | } 106 | int private_MatrixMultProblem(const MatricesSize& sizes, 107 | int i, int j) 108 | { 109 | if (i == j) 110 | { 111 | return 0; 112 | } 113 | int ans = Inf; 114 | for (int k = i; k < j; ++k) 115 | { 116 | int temp = private_MatrixMultProblem(sizes, i, k); 117 | temp += private_MatrixMultProblem(sizes, k + 1, j); 118 | temp += sizes[i].first * sizes[k + 1].first * sizes[j].second; 119 | ans = std::min(ans, temp); 120 | } 121 | return ans; 122 | } 123 | int algo::MatrixMultProblem(const MatricesSize& sizes) 124 | { 125 | return private_MatrixMultProblem(sizes, 0, sizes.size() - 1); 126 | } 127 | 128 | int private_NQueenProblem(int i, 129 | std::vector col, 130 | std::vector diag1, 131 | std::vector diag2) 132 | { 133 | const int n = col.size(); 134 | if (i == n) 135 | { 136 | return 1; 137 | } 138 | int ans = 0; 139 | for (int j = 0; j < n; ++j) 140 | { 141 | if (!col[j] && !diag1[i + j] && !diag2[i - j + n]) 142 | { 143 | col[j] = diag1[i + j] = diag2[i - j + n] = true; 144 | ans += private_NQueenProblem(i + 1, col, diag1, diag2); 145 | col[j] = diag1[i + j] = diag2[i - j + n] = false; 146 | } 147 | } 148 | return ans; 149 | } 150 | int NQueenProblem(int n) 151 | { 152 | std::vector col(n); 153 | std::vector diag1(2 * n + 1); 154 | std::vector diag2(2 * n + 1); 155 | return private_NQueenProblem(0, col, diag1, diag2); 156 | } 157 | } -------------------------------------------------------------------------------- /Algorithms/include/FamousProblems/Sudoku.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | namespace algo 6 | { 7 | class Sudoku 8 | { 9 | public: 10 | Sudoku(const std::string& sudoku); 11 | Sudoku(const Matrix& sudoku); 12 | }; 13 | } -------------------------------------------------------------------------------- /Algorithms/include/Geometry/Geometry.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include 4 | namespace algo 5 | { 6 | template 7 | struct Point2 8 | { 9 | T x, y; 10 | }; 11 | template 12 | struct Point3 13 | { 14 | T x, y, z; 15 | }; 16 | template 17 | double distance(Point2 f, Point2 s) 18 | { 19 | double dx = f.x - s.x; 20 | double dy = f.y - s.y; 21 | return sqrt(dx * dx + dy * dy); 22 | } 23 | template 24 | double distance(Point3 f, Point3 s) 25 | { 26 | double dx = f.x - s.x; 27 | double dy = f.y - s.y; 28 | double dz = f.z - s.z; 29 | return sqrt(dx * dx + dy * dy + dz * dz); 30 | } 31 | 32 | template 33 | struct Line2 34 | { 35 | T A, B, C; 36 | }; 37 | 38 | template 39 | Line2 CreateLine(Point2 f, Point2 s) 40 | { 41 | Line2 line; 42 | line.A = s.y - f.y; 43 | line.B = f.x - s.x; 44 | line.C = -(line.A * s.x + line.B * s.y); 45 | return line; 46 | } 47 | 48 | template 49 | double DistanceToLine(Line2 line, Point2 point) 50 | { 51 | return line.A * point.x + line.B * point.y + line.C; 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /Algorithms/include/Graph/Bipartite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"Graph.h" 4 | #include"Utils.h" 5 | namespace algo 6 | { 7 | class Bipartite 8 | { 9 | public: 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | 14 | private: 15 | std::vector m_used; 16 | bool dfs(int v); 17 | public: 18 | Bipartite(const ConnectionList & graph); 19 | 20 | Bipartite(const ConnectionMatrix& graph); 21 | 22 | Bipartite(const ListOfEdges& graph); 23 | 24 | }; 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/Bridges.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace algo 5 | { 6 | class Bridges 7 | { 8 | private: 9 | 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | using Edge = Graph::Edge; 14 | 15 | std::vector m_time_in; 16 | std::vector m_time_out; 17 | std::vector m_f_up; 18 | std::vector m_used; 19 | 20 | int m_timer; 21 | 22 | std::vector m_bridges; 23 | 24 | void dfs(const ConnectionList& graph, int v, int p = -1); 25 | 26 | public: 27 | Bridges(const Graph& graph); 28 | Bridges(const ConnectionList& graph); 29 | Bridges(const ConnectionMatrix& graph); 30 | Bridges(const ListOfEdges& graph); 31 | std::vector Get() const; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/ChromaticNumber.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace algo 4 | { 5 | class ChromaticNumber 6 | { 7 | private: 8 | 9 | using ConnectionList = Graph::ConnectionList; 10 | using ConnectionMatrix = Graph::ConnectionMatrix; 11 | using ListOfEdges = Graph::ListOfEdges; 12 | using Edge = Graph::Edge; 13 | using Color = Graph::Color; 14 | 15 | std::vector m_colors; 16 | int m_chromatic_number; 17 | 18 | void dfs(const ConnectionList& graph, int v); 19 | 20 | public: 21 | ChromaticNumber(const Graph& graph); 22 | ChromaticNumber(const ConnectionList& graph); 23 | ChromaticNumber(const ConnectionMatrix& graph); 24 | ChromaticNumber(const ListOfEdges& graph); 25 | std::vector GetColors() const; 26 | int GetNumber() const; 27 | }; 28 | } -------------------------------------------------------------------------------- /Algorithms/include/Graph/Components.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | namespace algo 7 | { 8 | class Components 9 | { 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | using VertexType = Graph::VertexType; 14 | 15 | Matrix m_components; 16 | std::vector m_used; 17 | private: 18 | void dfs(const ConnectionList & graph, int vertex); 19 | public: 20 | Components(const Graph& graph); 21 | Components(const ConnectionList& graph); 22 | Components(const ConnectionMatrix& graph); 23 | Components(const ListOfEdges& graph); 24 | 25 | size_t GetCount() const; 26 | std::vector GetComponent(int index) const; 27 | Matrix GetComponents() const; 28 | }; 29 | } -------------------------------------------------------------------------------- /Algorithms/include/Graph/CutPoints.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace algo 5 | { 6 | class CutPoints 7 | { 8 | private: 9 | 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | using VertexType = Graph::VertexType; 14 | 15 | std::vector m_time_in; 16 | std::vector m_f_up; 17 | std::vector m_used; 18 | 19 | int m_timer; 20 | 21 | std::vector m_cut_points; 22 | 23 | void dfs(const ConnectionList& graph, int v = 0, int p = -1); 24 | 25 | public: 26 | CutPoints(const Graph& graph); 27 | CutPoints(const ConnectionList& graph); 28 | CutPoints(const ConnectionMatrix& graph); 29 | CutPoints(const ListOfEdges& graph); 30 | std::vector Get() const; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/CycleChecker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | class CycleChecker 7 | { 8 | using ConnectionList = Graph::ConnectionList; 9 | using ConnectionMatrix = Graph::ConnectionMatrix; 10 | using ListOfEdges = Graph::ListOfEdges; 11 | using VertexType = Graph::VertexType; 12 | 13 | using VertexState = Graph::VertexState; 14 | 15 | std::vector m_vertices_state; 16 | 17 | std::vector m_parents; 18 | int m_cycle_start, m_cycle_end; 19 | 20 | 21 | bool m_cycle_found; 22 | std::vector m_cycle; 23 | 24 | private: 25 | bool dfs(const ConnectionList & graph, int vertex); 26 | public: 27 | CycleChecker(const Graph& graph); 28 | CycleChecker(const ConnectionList& graph); 29 | CycleChecker(const ConnectionMatrix& graph); 30 | CycleChecker(const ListOfEdges& graph); 31 | 32 | bool HasCycle() const; 33 | std::vector GetCycle() const; 34 | 35 | 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/DSU.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace algo 6 | { 7 | class DSU 8 | { 9 | using Vertex = Graph::VertexType; 10 | 11 | std::vector m_parent; 12 | std::vector m_size; 13 | public: 14 | DSU(int number_of_elements = 0); 15 | 16 | Vertex GetParent(Vertex vertex); 17 | void Union(Vertex first, Vertex second); 18 | int MakeNewSet(); 19 | std::vector GetGroup(Vertex element); 20 | }; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/Dijkstra.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include"Utils.h" 5 | namespace algo 6 | { 7 | class Dijkstra 8 | { 9 | public: 10 | // using Edge = std::pair; 11 | // template 12 | // using WeightedEdge = std::pair, int>; 13 | using ConnectionList = Graph::ConnectionList; 14 | using ConnectionMatrix = Graph::ConnectionMatrix; 15 | using ListOfEdges = Graph::ListOfEdges; 16 | 17 | private: 18 | // std::vector> m_graph; 19 | std::vector m_distance; 20 | std::vector m_parents; 21 | int m_start_vertex; 22 | 23 | 24 | public: 25 | Dijkstra(const Graph& graph, int start_vertex); 26 | Dijkstra(const ConnectionList& graph, int start_vertex); 27 | Dijkstra(const ConnectionMatrix& graph, int start_vertex); 28 | Dijkstra(const ListOfEdges& graph, int start_vertex); 29 | 30 | Graph::WeightType GetDistance(int to) const; 31 | std::vector GetDistance() const; 32 | std::vector GetPath(int to) const; 33 | 34 | }; 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/Euler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | class Euler 7 | { 8 | using ConnectionList = Graph::ConnectionList; 9 | using ConnectionMatrix = Graph::ConnectionMatrix; 10 | using ListOfEdges = Graph::ListOfEdges; 11 | using VertexType = Graph::VertexType; 12 | 13 | using VertexState = Graph::VertexState; 14 | 15 | bool m_has_path; 16 | bool m_has_cycle; 17 | std::vector m_cycle; 18 | std::set> m_used; 19 | 20 | private: 21 | void dfs(const ConnectionList & graph, int vertex); 22 | public: 23 | Euler(const Graph& graph); 24 | Euler(const ConnectionList& graph); 25 | Euler(const ConnectionMatrix& graph); 26 | Euler(const ListOfEdges& graph); 27 | 28 | bool HasPath() const; 29 | bool HasCycle() const; 30 | std::vector GetCycle() const; 31 | 32 | 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/FloydWarshall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include"Graph.h" 4 | 5 | namespace algo 6 | { 7 | class FloydWarshall 8 | { 9 | using ConnectionList = Graph::ConnectionList; 10 | using ConnectionMatrix = Graph::ConnectionMatrix; 11 | using ListOfEdges = Graph::ListOfEdges; 12 | using WeightType = Graph::WeightType; 13 | 14 | ConnectionMatrix m_distances; 15 | Matrix m_parents; 16 | void get_path(int from, int to, std::vector& path); 17 | public: 18 | 19 | FloydWarshall(const Graph& graph); 20 | FloydWarshall(const ConnectionList& connection_list); 21 | FloydWarshall(const ConnectionMatrix& connection_matrix); 22 | FloydWarshall(const ListOfEdges& list_of_edges); 23 | 24 | WeightType GetDistance(int from, int to) const; 25 | std::vector GetDistance(int from) const; 26 | std::vector GetPath(int from, int to) const; 27 | 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/FordBellman.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"Graph.h" 4 | #include"Utils.h" 5 | namespace algo 6 | { 7 | class FordBellman 8 | { 9 | public: 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | 14 | private: 15 | int n; 16 | std::vector m_distance; 17 | std::vector m_parents; 18 | int m_start_vertex; 19 | 20 | 21 | public: 22 | FordBellman(const Graph& graph, int start_vertex); 23 | FordBellman(const ConnectionList& graph, int start_vertex); 24 | FordBellman(const ConnectionMatrix& graph, int start_vertex); 25 | FordBellman(const ListOfEdges& graph, int start_vertex); 26 | 27 | Graph::WeightType GetDistance(int to) const; 28 | std::vector GetDistance() const; 29 | std::vector GetPath(int to) const; 30 | 31 | }; 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/Graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include"Utils.h" 6 | namespace algo 7 | { 8 | class Graph 9 | { 10 | public: 11 | using VertexType = int; 12 | using WeightType = long long; 13 | using Color = int; 14 | struct Edge 15 | { 16 | VertexType from; 17 | VertexType to; 18 | WeightType weight; 19 | Edge(); 20 | Edge(VertexType from, VertexType to, WeightType weight); 21 | Edge(VertexType from, VertexType to); 22 | bool operator< (const Edge& other) const; 23 | // TODO: investigate why adding const to operator== 24 | // cause compile error 25 | bool operator==(const Edge& other); 26 | // Edge(int to, int weight = 1); 27 | }; 28 | 29 | enum class VertexState { 30 | NotVisited, 31 | Visited, 32 | Exited, 33 | }; 34 | 35 | using ConnectionList = Matrix; 36 | using ConnectionMatrix = Matrix; 37 | using ListOfEdges = std::vector; 38 | 39 | /*enum class Type 40 | { 41 | ConnectionList, 42 | ConnectionMatrix, 43 | ListOfEdges, 44 | };*/ 45 | 46 | class WeightLess 47 | { 48 | public: 49 | typedef Edge value_type; 50 | typedef Edge first_argument_type; 51 | typedef Edge second_argument_type; 52 | typedef bool result_type; 53 | 54 | bool 55 | operator() 56 | (const Edge& first, const Edge& second) const; 57 | }; 58 | class WeightGreater 59 | { 60 | public: 61 | typedef Edge value_type; 62 | typedef Edge first_argument_type; 63 | typedef Edge second_argument_type; 64 | typedef bool result_type; 65 | 66 | bool 67 | operator() 68 | (const Edge& first, const Edge& second) const; 69 | }; 70 | 71 | static ConnectionList 72 | Reverse 73 | (const ConnectionList& graph); 74 | 75 | static ListOfEdges 76 | Reverse 77 | (const ListOfEdges& graph); 78 | 79 | static ConnectionMatrix 80 | Reverse 81 | (const ConnectionMatrix& graph); 82 | 83 | static ConnectionList 84 | ListOfEdgesToConnectionList 85 | (const ListOfEdges& list_of_edges, bool oriented = true); 86 | static ConnectionList 87 | LOE2CL 88 | (const ListOfEdges& list_of_edges, bool oriented = true); 89 | 90 | static ConnectionList 91 | ConnectionMatrixToConnectionList 92 | (const ConnectionMatrix& connection_matrix); 93 | static ConnectionList 94 | CM2CL 95 | (const ConnectionMatrix& connection_matrix); 96 | 97 | static ListOfEdges 98 | ConnectionListToListOfEdges 99 | (const ConnectionList& connection_list); 100 | static ListOfEdges 101 | CL2LOE 102 | (const ConnectionList& connection_list); 103 | 104 | static ListOfEdges 105 | ConnectionMatrixToListOfEdges 106 | (const ConnectionMatrix& connection_matrix); 107 | static ListOfEdges 108 | CM2LOE 109 | (const ConnectionMatrix& connection_matrix); 110 | 111 | static ConnectionMatrix 112 | ListOfEdgesToConnectionMatrix 113 | (const ListOfEdges& list_of_edges, bool oriented = true); 114 | static ConnectionMatrix 115 | LOE2CM 116 | (const ListOfEdges& list_of_edges, bool oriented = true); 117 | 118 | static ConnectionMatrix 119 | ConnectionListToConnectionMatrix 120 | (const ConnectionList& connection_list); 121 | static ConnectionMatrix 122 | CL2CM 123 | (const ConnectionList& connection_list); 124 | 125 | static ConnectionMatrix 126 | MakeUndirected 127 | (ConnectionMatrix& connection_matrix); 128 | 129 | static ConnectionList 130 | MakeUndirected 131 | (ConnectionList& connection_list); 132 | 133 | static ListOfEdges 134 | MakeUndirected 135 | (ListOfEdges& list_of_edges); 136 | 137 | static size_t 138 | GetSize 139 | (const ConnectionMatrix& connection_matrix); 140 | 141 | static size_t 142 | GetSize 143 | (const ConnectionList& connection_list); 144 | 145 | static size_t 146 | GetSize 147 | (const ListOfEdges& list_of_edges); 148 | 149 | static ListOfEdges 150 | RandomGraph(int number_of_vertices = 1000, 151 | int number_of_edges = 100000, 152 | WeightType weight = 10); 153 | 154 | static void 155 | UniqifyListOfEdges 156 | (ListOfEdges& list_of_edges); 157 | 158 | static void 159 | NormalizeListOfEdges 160 | (ListOfEdges& list_of_edges); 161 | 162 | Graph(const ConnectionList& connection_list); 163 | Graph(const ConnectionMatrix& connection_matrix); 164 | Graph(const ListOfEdges& list_of_edges); 165 | ConnectionList AsConnectionList() const; 166 | ConnectionMatrix AsConnectionMatrix() const; 167 | ListOfEdges AsListOfEdges() const; 168 | size_t GetSize() const; 169 | bool isBipartite() const; 170 | bool isTree() const; 171 | 172 | private: 173 | mutable ConnectionList m_connection_list; 174 | mutable ConnectionMatrix m_connection_matrix; 175 | mutable ListOfEdges m_list_of_edges; 176 | /* template 177 | class Node 178 | { 179 | std::set< 180 | std::pair< 181 | std::shared_ptr, 182 | EdgeType 183 | > 184 | > m_neighbours; 185 | 186 | int m_index; 187 | public: 188 | Node(int index); 189 | void AddEdge(std::shared_ptr neighbour, 190 | EdgeType weight = EdgeType()); 191 | 192 | void Clean(); 193 | 194 | bool operator< (std::shared_ptr other) 195 | { 196 | return this->m_index < other->m_index; 197 | } 198 | }; 199 | */ 200 | /* 201 | std::vector> m_graph; 202 | public: 203 | Graph(const std::vector>& graph, )*/ 204 | }; 205 | 206 | //class GraphTypeTag {}; 207 | //class ConnectionListTag : public GraphTypeTag {}; 208 | //class ConnectionMatrixTag : public GraphTypeTag {}; 209 | //class ListOfEdgesTag : public GraphTypeTag {}; 210 | bool operator==(const Graph::Edge& first, const Graph::Edge& second); 211 | inline void PrintTo(const Graph::Edge &edge, ::std::ostream *os) 212 | { 213 | *os << "{" << edge.from 214 | << ", " << edge.to 215 | << ", " << edge.weight 216 | << "}"; 217 | } 218 | }; 219 | 220 | 221 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/Khun.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"Graph.h" 4 | #include"Utils.h" 5 | namespace algo 6 | { 7 | class Khun 8 | { 9 | public: 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | 14 | private: 15 | int n; 16 | std::vector m_distance; 17 | std::vector m_parents; 18 | int m_start_vertex; 19 | 20 | bool dfs(const ConnectionList& graph, int v); 21 | 22 | public: 23 | Khun(const Graph& graph); 24 | Khun(const ConnectionList& graph); 25 | Khun(const ConnectionMatrix& graph); 26 | Khun(const ListOfEdges& graph); 27 | 28 | std::vector Get() const; 29 | 30 | }; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/Kruskal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | class Kruskal 7 | { 8 | private: 9 | 10 | using ConnectionList = Graph::ConnectionList; 11 | using ConnectionMatrix = Graph::ConnectionMatrix; 12 | using ListOfEdges = Graph::ListOfEdges; 13 | 14 | 15 | algo::DSU m_dsu; 16 | Graph::WeightType m_cost; 17 | ListOfEdges m_spanning_tree; 18 | 19 | 20 | public: 21 | Kruskal(const Graph& graph); 22 | Kruskal(const ConnectionList & graph); 23 | Kruskal(const ConnectionMatrix& graph); 24 | Kruskal(const ListOfEdges& graph); 25 | 26 | std::vector GetTree() const; 27 | Graph::WeightType GetCost() const; 28 | 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/LCA.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | 7 | class LCA 8 | { 9 | using ConnectionList = Graph::ConnectionList; 10 | using ConnectionMatrix = Graph::ConnectionMatrix; 11 | using ListOfEdges = Graph::ListOfEdges; 12 | using VertexType = Graph::VertexType; 13 | 14 | std::vector m_time_in; 15 | std::vector m_time_out; 16 | std::vector> m_up; 17 | 18 | int m_timer; 19 | 20 | void dfs(const ConnectionList& graph, int vertex = 0, int prev = 0); 21 | bool upper(int a, int b) const; 22 | static int greater_power_of_2(int n); 23 | 24 | public: 25 | LCA(const Graph& graph); 26 | LCA(const ConnectionList& graph); 27 | LCA(const ConnectionMatrix& graph); 28 | LCA(const ListOfEdges& graph); 29 | 30 | int Get(int a, int b) const; 31 | }; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Algorithms/include/Graph/PruferCode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace algo 7 | { 8 | class PruferCode 9 | { 10 | public: 11 | PruferCode(); 12 | std::vector Encode(const Graph& graph); 13 | Graph Decode(const std::vector& graph); 14 | }; 15 | 16 | } -------------------------------------------------------------------------------- /Algorithms/include/Graph/StrongComponents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace algo 5 | { 6 | class StrongComponents 7 | { 8 | using ConnectionList = Graph::ConnectionList; 9 | using ConnectionMatrix = Graph::ConnectionMatrix; 10 | using ListOfEdges = Graph::ListOfEdges; 11 | using VertexType = Graph::VertexType; 12 | 13 | Matrix m_components; 14 | std::vector m_used; 15 | 16 | private: 17 | void dfs(const ConnectionList & graph, int vertex); 18 | public: 19 | StrongComponents(const Graph& graph); 20 | StrongComponents(const ConnectionList& graph); 21 | StrongComponents(const ConnectionMatrix& graph); 22 | StrongComponents(const ListOfEdges& graph); 23 | 24 | int GetCount() const; 25 | std::vector GetComponent(int index) const; 26 | Matrix GetComponents() const; 27 | }; 28 | } -------------------------------------------------------------------------------- /Algorithms/include/Graph/Toposort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace algo 4 | { 5 | 6 | class Toposort 7 | { 8 | using ConnectionList = Graph::ConnectionList; 9 | using ConnectionMatrix = Graph::ConnectionMatrix; 10 | using ListOfEdges = Graph::ListOfEdges; 11 | using VertexType = Graph::VertexType; 12 | 13 | using VertexState = Graph::VertexState; 14 | 15 | std::vector m_sorted_vertices; 16 | std::vector m_used; 17 | 18 | void dfs(const ConnectionList & graph, int vertex); 19 | 20 | public: 21 | Toposort(const Graph& graph); 22 | Toposort(const ConnectionList& graph); 23 | Toposort(const ConnectionMatrix& graph); 24 | Toposort(const ListOfEdges& graph); 25 | 26 | std::vector GetNewVerticesIndices() const; 27 | }; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Algorithms/include/Math/Math.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | // TODO check math 7 | namespace algo 8 | { 9 | template 10 | inline T gcd(T a, T b) 11 | { 12 | return b ? gcd(b, a % b) : a; 13 | } 14 | 15 | template 16 | inline T lcm(T a, T b) 17 | { 18 | return a / gcd(a, b) * b; 19 | } 20 | 21 | inline int euler(int n) 22 | { 23 | int ans = 0; 24 | for (int i = 1; i <= n; ++i) 25 | { 26 | ans += gcd(i, n) == 1; 27 | } 28 | return ans; 29 | } 30 | inline long long fast_euler(long long n) 31 | { 32 | long long ans = n; 33 | long long prime = 2; 34 | while (n >= prime * prime) 35 | { 36 | if (n % prime == 0) 37 | { 38 | ans = ans / prime * (prime - 1); 39 | while (n % prime == 0) 40 | n /= prime; 41 | } 42 | ++prime; 43 | } 44 | if (n != 1) 45 | ans = ans / n * (n - 1); 46 | return ans; 47 | } 48 | 49 | template 50 | inline T bin_pow(T elem, int n) 51 | { 52 | T ans = 1; 53 | while (n) 54 | { 55 | if (n & 1) 56 | { 57 | ans = ans * elem; 58 | } 59 | elem = elem * elem; 60 | n >>= 1; 61 | } 62 | return ans; 63 | } 64 | 65 | template 66 | inline T bin_pow(T elem, int n, T neutral_element, 67 | Func mul = std::multiplies()) 68 | { 69 | T ans = neutral_element; 70 | while (n) 71 | { 72 | if (n & 1) 73 | { 74 | ans = mul(ans, elem); 75 | } 76 | elem = mul(elem, elem); 77 | n >>= 1; 78 | } 79 | return ans; 80 | } 81 | template 82 | inline T bin_pow(T elem, int n, int mod, T neutral_element, 83 | Func mul = std::multiplies(), 84 | Func modulus = std::modulus()) 85 | { 86 | T ans = neutral_element; 87 | while (n) 88 | { 89 | if (n & 1) 90 | { 91 | ans = mul(ans, elem); 92 | ans = modulus(ans, mod); 93 | } 94 | elem = mul(elem, elem); 95 | elem = modulus(elem, mod); 96 | n >>= 1; 97 | } 98 | return ans; 99 | } 100 | 101 | template 102 | inline algo::Matrix matrix_mul(const algo::Matrix& l, 103 | const algo::Matrix& r) 104 | { 105 | if (l[0].size() != r.size()) 106 | { 107 | throw std::runtime_error("Matrix dimensions must be equal"); 108 | } 109 | algo::Matrix matrix = CreateMatrix(l.size(), r[0].size(), 0); 110 | for (int i = 0; i < l.size(); ++i) 111 | for (int j = 0; j < r.size(); ++j) 112 | for (int k = 0; k < l[i].size(); ++k) 113 | matrix[i][j] += l[i][k] * r[k][j]; 114 | return matrix; 115 | 116 | } 117 | 118 | template 119 | inline algo::Matrix matrix_mod(algo::Matrix matrix, int mod) 120 | { 121 | for (int i = 0; i < matrix.size(); ++i) 122 | for (int j = 0; j < matrix[i].size(); ++j) 123 | matrix[i][j] %= mod; 124 | return matrix; 125 | 126 | } 127 | 128 | inline std::vector sieve_of_eratosthenes(int n) 129 | { 130 | std::vector primes(1, 2); 131 | std::vector used(n, false); 132 | for (int i = 2; i < used.size(); i += 2) 133 | used[i] = true; 134 | for (long long i = 3; i < used.size(); i += 2) 135 | { 136 | if (!used[i]) 137 | { 138 | primes.push_back(i); 139 | for (long long j = i * i; j < used.size(); j += i) 140 | { 141 | used[j] = true; 142 | } 143 | } 144 | } 145 | return primes; 146 | } 147 | inline int extended_euclidean(int a, int b, int& x, int& y) 148 | { 149 | if (a == 0) 150 | { 151 | x = 0, y = 1; 152 | return b; 153 | } 154 | int x1, y1; 155 | int gcd = extended_euclidean(b % a, a, x1, y1); 156 | x = y1 - b / a * x1; 157 | y = x1; 158 | return gcd; 159 | } 160 | } 161 | 162 | 163 | -------------------------------------------------------------------------------- /Algorithms/include/Sortings/Sorting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace algo 9 | { 10 | //template 11 | //void sort(const Iter& first, const Iter& second); 12 | 13 | template 14 | void BubbleSort(Iter first, Iter last) 15 | { 16 | for (Iter i = first; i != last; i = std::next(i)) 17 | { 18 | for (Iter j = first; j < i; j = std::next(j)) 19 | { 20 | if (*i < *j) 21 | { 22 | std::iter_swap(i, j); 23 | } 24 | } 25 | } 26 | } 27 | template 28 | void SelectionSort(Iter first, Iter last) 29 | { 30 | for (Iter i = first; i != last; i = std::next(i)) 31 | { 32 | Iter min = i; 33 | for (Iter j = i; j < last; j = std::next(j)) 34 | { 35 | if (*j < *min) 36 | { 37 | min = j; 38 | } 39 | } 40 | std::iter_swap(i, min); 41 | } 42 | } 43 | 44 | template 45 | void InsertionSort(Iter first, Iter last) 46 | { 47 | for (Iter i = std::next(first); i != last; i = std::next(i)) 48 | { 49 | Iter temp = i; 50 | while (temp != first) 51 | { 52 | if (*temp < *std::prev(temp)) 53 | { 54 | std::iter_swap(temp, std::prev(temp)); 55 | } 56 | temp = std::prev(temp); 57 | } 58 | } 59 | } 60 | 61 | template 62 | void RadixSort(Iter first, Iter last) 63 | // this sort must work only for ints 64 | { 65 | std::vector vec(first, last); 66 | int power_of_ten = 1; 67 | std::vector> buckets(10); 68 | for (int pow = 0; pow < 10; ++pow) 69 | { 70 | for (Iter i = vec.begin(); i != vec.end(); i = std::next(i)) 71 | { 72 | buckets[(*i) / power_of_ten % 10].push_back(*i); 73 | } 74 | vec.clear(); 75 | for (int i = 0; i < buckets.size(); ++i) 76 | { 77 | vec.insert(vec.end(), buckets[i].begin(), buckets[i].end()); 78 | buckets[i].clear(); 79 | } 80 | power_of_ten *= 10; 81 | } 82 | std::copy(vec.begin(), vec.end(), first); 83 | } 84 | template 85 | void HeapSort(Iter first, Iter last) 86 | { 87 | using type = typename Iter::value_type; 88 | std::priority_queue, 90 | std::greater> pq(first, last); 91 | while (!pq.empty()) 92 | { 93 | *first = pq.top(); 94 | first = std::next(first); 95 | pq.pop(); 96 | } 97 | } 98 | 99 | template 100 | void merge(Iter first_begin, Iter first_end, 101 | Iter second_begin, Iter second_end, 102 | Iter out_begin) 103 | { 104 | while (first_begin < first_end && second_begin < second_end) 105 | { 106 | *out_begin++ = *first_begin < *second_begin ? *first_begin++ 107 | : *second_begin++; 108 | } 109 | while (first_begin < first_end) 110 | { 111 | *out_begin++ = *first_begin++; 112 | } 113 | while (second_begin < second_end) 114 | { 115 | *out_begin++ = *second_begin++; 116 | } 117 | } 118 | 119 | template 120 | void MergeSort(Iter first, Iter last) 121 | { 122 | int size = std::distance(first, last); 123 | if (size == 1) 124 | return; 125 | int half = size / 2; 126 | using type = typename Iter::value_type; 127 | Iter mid = first; 128 | std::advance(mid, half); 129 | std::vector f_v(first, mid); 130 | std::vector s_v(mid, last); 131 | MergeSort(f_v.begin(), f_v.end()); 132 | MergeSort(s_v.begin(), s_v.end()); 133 | merge(f_v.begin(), f_v.end(), s_v.begin(), s_v.end(), first); 134 | } 135 | 136 | template 137 | Iter partition(Iter first, Iter last) 138 | { 139 | typename Iter::value_type pivot = *first; 140 | Iter out = first; 141 | 142 | for (Iter temp = std::next(first); temp != last; temp=std::next(temp)) 143 | { 144 | if (*temp < pivot) 145 | { 146 | out = std::next(out); 147 | std::iter_swap(out, temp); 148 | } 149 | } 150 | std::iter_swap(out, first); 151 | return out; 152 | } 153 | 154 | template 155 | void QuickSort(Iter first, Iter last) 156 | { 157 | if (std::distance(first, last) > 1) 158 | { 159 | Iter mid = partition(first, last); 160 | QuickSort(first, mid); 161 | QuickSort(std::next(mid), last); 162 | } 163 | } 164 | } -------------------------------------------------------------------------------- /Algorithms/include/Strings/KnuthMorrisPratt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace algo 8 | { 9 | class KnuthMorrisPratt 10 | { 11 | private: 12 | std::vector m_occurs; 13 | PrefixFunction m_prefix; 14 | int m_first_size; 15 | void calculate(); 16 | public: 17 | KnuthMorrisPratt(const std::string& str1, 18 | const std::string& str2); 19 | std::vector Get() const; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /Algorithms/include/Strings/PrefixFunction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace algo 7 | { 8 | class PrefixFunction 9 | { 10 | private: 11 | std::string m_str; 12 | std::vector m_prefix; 13 | void calculate(); 14 | public: 15 | PrefixFunction(const std::string& str); 16 | std::vector Get() const; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /Algorithms/include/Strings/StringHashing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | namespace algo 6 | { 7 | class StringHashing 8 | { 9 | public: 10 | typedef unsigned long long HashType; 11 | private: 12 | const int m_prime = 331; 13 | private: 14 | HashType m_mod; 15 | std::string m_str; 16 | std::vector m_hashes; 17 | std::vector m_primes; 18 | private: 19 | void build_hash(); 20 | public: 21 | explicit StringHashing(const std::string& str, 22 | HashType mod = ULLONG_MAX); 23 | 24 | HashType Get() const; 25 | HashType Get(int i, int j) const; 26 | std::size_t Size() const; 27 | 28 | }; 29 | } -------------------------------------------------------------------------------- /Algorithms/include/Strings/ZFunction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace algo 7 | { 8 | class Z_Function 9 | { 10 | private: 11 | std::string m_str; 12 | std::vector m_z; 13 | void calculate(); 14 | public: 15 | Z_Function(const std::string& str); 16 | std::vector Get() const; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /Algorithms/include/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace algo 13 | { 14 | const int Inf = INT_MAX; 15 | const long long LInf = LLONG_MAX; 16 | 17 | template 18 | T max(T first, Others... others); 19 | 20 | template 21 | T max(T first); 22 | 23 | template 24 | T min(T first, Others... others); 25 | 26 | template 27 | T min(T first); 28 | 29 | template 30 | void input_container(std::istream& in, 31 | int& n, 32 | Container& container); 33 | 34 | template 35 | void output_container(std::ostream& out, 36 | const Container& container, 37 | const std::string& delimiter = " "); 38 | 39 | template 40 | void sum_container(const Container& container, T& sum); 41 | 42 | 43 | template 44 | using Matrix = std::vector>; 45 | 46 | template 47 | Matrix CreateMatrix(size_t n, T etalon = T()); 48 | 49 | template 50 | Matrix CreateMatrix(size_t n, size_t m, T etalon = T()); 51 | 52 | template 53 | void CreateMatrix(Matrix& matrix, size_t n, T etalon = T()); 54 | 55 | template 56 | void CreateMatrix(Matrix& matrix, size_t n, size_t m, T etalon = T()); 57 | 58 | double random(double min, double max); 59 | } 60 | 61 | #include "Utils.hpp" 62 | 63 | 64 | -------------------------------------------------------------------------------- /Algorithms/include/Utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"Utils.h" 4 | #include 5 | namespace algo 6 | { 7 | template 8 | inline T max(T first, Others... others) 9 | { 10 | return std::max(first, max(others...)); 11 | } 12 | template 13 | inline T max(T first) 14 | { 15 | return first; 16 | } 17 | 18 | template 19 | inline T min(T first, Others... others) 20 | { 21 | return std::min(first, min(others...)); 22 | } 23 | template 24 | inline T min(T first) 25 | { 26 | return first; 27 | } 28 | 29 | template 30 | inline void sum_container(const Container& container, T& sum) 31 | { 32 | for (auto& elem : container) 33 | { 34 | sum += elem; 35 | } 36 | } 37 | 38 | template 39 | inline Matrix CreateMatrix(size_t n, T etalon) 40 | { 41 | return Matrix(n, std::vector(n, etalon)); 42 | } 43 | 44 | template 45 | inline Matrix CreateMatrix(size_t n, size_t m, T etalon) 46 | { 47 | return Matrix(n, std::vector(m, etalon)); 48 | } 49 | 50 | template 51 | inline void CreateMatrix(Matrix& matrix, size_t n, T etalon) 52 | { 53 | matrix = Matrix(n, std::vector(n, etalon)); 54 | } 55 | 56 | template 57 | inline void CreateMatrix(Matrix& matrix, size_t n, size_t m, T etalon) 58 | { 59 | matrix = Matrix(n, std::vector(m, etalon)); 60 | } 61 | 62 | inline double random(double min, double max) 63 | { 64 | std::random_device rd; 65 | std::mt19937 mt(rd()); 66 | std::uniform_real_distribution dist(min, max); 67 | return dist(mt); 68 | } 69 | 70 | template 71 | inline void input_container(std::istream& in, 72 | int& n, 73 | Container& container) 74 | { 75 | in >> n; 76 | container.resize(n); 77 | for (auto& elem : container) 78 | { 79 | in >> elem; 80 | } 81 | } 82 | 83 | template 84 | inline void output_container(std::ostream& out, 85 | const Container& container, 86 | const std::string& delimiter) 87 | { 88 | for (auto& elem : container) 89 | { 90 | out << elem << delimiter; 91 | } 92 | } 93 | } 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Algorithms/src/DataStructures/Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | namespace algo 3 | { 4 | Trie::Node::Node() 5 | : alphabet(AlphabetSize, nullptr) 6 | , word_end(false) 7 | { 8 | } 9 | /*Trie::Trie(TrieType type) 10 | : m_type(type) 11 | { 12 | }*/ 13 | int Trie::index_of_char(char ch) 14 | { 15 | return ch - 'a'; 16 | } 17 | void Trie::add_word(Node*& curr_node, 18 | const std::string& word, 19 | int index) 20 | { 21 | if (curr_node == nullptr) 22 | { 23 | curr_node = new Node(); 24 | } 25 | if (word.size() == index) 26 | { 27 | curr_node->word_end = true; 28 | return; 29 | } 30 | Node*& next = curr_node->alphabet[index_of_char(word[index])]; 31 | return add_word(next, word, index + 1); 32 | } 33 | bool Trie::find_word(Node* const& curr_node, 34 | const std::string& word, 35 | int index) const 36 | { 37 | if (curr_node == nullptr) 38 | { 39 | return false; 40 | } 41 | if (index == word.size()) 42 | { 43 | return curr_node->word_end; 44 | } 45 | Node* next = curr_node->alphabet[index_of_char(word[index])]; 46 | return find_word(next, word, index + 1); 47 | } 48 | Trie::Trie() 49 | : m_root(nullptr) 50 | { 51 | } 52 | void Trie::add_word(const std::string& word) 53 | { 54 | return add_word(m_root, word, 0); 55 | } 56 | bool Trie::find_word(const std::string& word) const 57 | { 58 | return find_word(m_root, word, 0); 59 | } 60 | } -------------------------------------------------------------------------------- /Algorithms/src/Geometry/Geometry.cpp: -------------------------------------------------------------------------------- 1 | #include"Geometry/Geometry.h" 2 | 3 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/Bipartite.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph/Bipartite.h" 2 | 3 | algo::Bipartite::Bipartite(const ConnectionList & graph) 4 | { 5 | } 6 | 7 | algo::Bipartite::Bipartite(const ConnectionMatrix & graph) 8 | { 9 | } 10 | 11 | algo::Bipartite::Bipartite(const ListOfEdges & graph) 12 | { 13 | } 14 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/Bridges.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | void Bridges::dfs(const ConnectionList& graph, int v, int p) 6 | { 7 | m_used[v] = true; 8 | m_time_in[v] = m_f_up[v] = ++m_timer; 9 | 10 | for (int i = 0; i < graph[v].size(); ++i) 11 | { 12 | int to = graph[v][i].to; 13 | if (to == p) 14 | { 15 | continue; 16 | } 17 | if (m_used[to]) 18 | { 19 | m_f_up[v] = min(m_f_up[v], m_time_in[to]); 20 | } 21 | else 22 | { 23 | dfs(graph, to, v); 24 | m_f_up[v] = min(m_f_up[v], m_f_up[to]); 25 | if (m_f_up[to] > m_time_in[v]) 26 | { 27 | m_bridges.push_back({v, to}); 28 | } 29 | } 30 | } 31 | } 32 | 33 | Bridges::Bridges(const Graph& graph) 34 | : Bridges(graph.AsConnectionList()) 35 | { 36 | } 37 | 38 | Bridges::Bridges(const ConnectionList& graph) 39 | : m_timer(0) 40 | , m_time_in(graph.size()) 41 | , m_time_out(graph.size()) 42 | , m_used(graph.size()) 43 | , m_f_up(graph.size()) 44 | { 45 | for (int i = 0; i < m_used.size(); ++i) 46 | { 47 | if (!m_used[i]) 48 | { 49 | dfs(graph, i); 50 | } 51 | std::sort(m_bridges.begin(), m_bridges.end()); 52 | auto iter = std::unique(m_bridges.begin(), m_bridges.end()); 53 | m_bridges.erase(iter, m_bridges.end()); 54 | } 55 | } 56 | 57 | Bridges::Bridges(const ConnectionMatrix& graph) 58 | : Bridges(Graph::CM2CL(graph)) 59 | { 60 | } 61 | 62 | Bridges::Bridges(const ListOfEdges& graph) 63 | : Bridges(Graph::LOE2CL(graph)) 64 | { 65 | } 66 | std::vector Bridges::Get() const 67 | { 68 | return m_bridges; 69 | } 70 | } -------------------------------------------------------------------------------- /Algorithms/src/Graph/ChromaticNumber.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph\ChromaticNumber.h" 2 | #include "Defines.h" 3 | namespace algo 4 | { 5 | void ChromaticNumber::dfs(const ConnectionList& graph, int v) 6 | { 7 | if (m_colors[v] != -1) 8 | { 9 | return; 10 | } 11 | std::vector used_colors; 12 | for (int i = 0; i < graph[v].size(); ++i) 13 | { 14 | int to = graph[v][i].to; 15 | if (m_colors[to] != -1) 16 | { 17 | used_colors.push_back(m_colors[to]); 18 | } 19 | } 20 | so(used_colors); 21 | int color = -1; 22 | for (int i = 0; i < used_colors.size(); ++i) 23 | { 24 | if (used_colors[i] != i) 25 | { 26 | color = i; 27 | break; 28 | } 29 | } 30 | if (color == -1) 31 | { 32 | color = used_colors.size(); 33 | } 34 | m_colors[v] = color; 35 | for (int i = 0; i < graph[v].size(); ++i) 36 | { 37 | int to = graph[v][i].to; 38 | dfs(graph, to); 39 | } 40 | } 41 | 42 | ChromaticNumber::ChromaticNumber(const Graph& graph) 43 | : ChromaticNumber(graph.AsConnectionList()) 44 | { 45 | } 46 | 47 | ChromaticNumber::ChromaticNumber(const ConnectionList& graph) 48 | : m_colors(graph.size(), -1) 49 | , m_chromatic_number(0) 50 | { 51 | for (int i = 0; i < graph.size(); ++i) 52 | { 53 | if (m_colors[i] == -1) 54 | { 55 | dfs(graph, i); 56 | } 57 | } 58 | m_chromatic_number = *std::max_element(m_colors.begin(), 59 | m_colors.end()) + 1; 60 | } 61 | 62 | ChromaticNumber::ChromaticNumber(const ConnectionMatrix& graph) 63 | : ChromaticNumber(Graph::CM2CL(graph)) 64 | { 65 | } 66 | 67 | ChromaticNumber::ChromaticNumber(const ListOfEdges& graph) 68 | : ChromaticNumber(Graph::LOE2CL(graph)) 69 | { 70 | } 71 | std::vector ChromaticNumber::GetColors() const 72 | { 73 | return m_colors; 74 | } 75 | int ChromaticNumber::GetNumber() const 76 | { 77 | return m_chromatic_number; 78 | } 79 | } -------------------------------------------------------------------------------- /Algorithms/src/Graph/Components.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph\Components.h" 2 | 3 | 4 | namespace algo 5 | { 6 | 7 | void Components::dfs(const ConnectionList & graph, int vertex) 8 | { 9 | m_used[vertex] = true; 10 | m_components.back().push_back(vertex); 11 | for (auto& neighbours : graph[vertex]) 12 | { 13 | if (!m_used[neighbours.to]) 14 | { 15 | dfs(graph, neighbours.to); 16 | } 17 | } 18 | } 19 | 20 | Components::Components(const Graph& graph) 21 | : Components(graph.AsConnectionList()) 22 | { 23 | } 24 | 25 | Components::Components(const ConnectionList & graph) 26 | : m_used(Graph::GetSize(graph)) 27 | { 28 | size_t graph_size = Graph::GetSize(graph); 29 | for (size_t i = 0; i < graph_size; i++) 30 | { 31 | if (!m_used[i]) 32 | { 33 | m_components.push_back({}); 34 | dfs(graph, (int)i); 35 | } 36 | } 37 | for (auto& component : m_components) 38 | { 39 | std::sort(component.begin(), component.end()); 40 | } 41 | std::sort(m_components.begin(), m_components.end()); 42 | } 43 | 44 | Components::Components(const ConnectionMatrix & graph) 45 | : Components(Graph::CM2CL(graph)) 46 | { 47 | } 48 | 49 | Components::Components(const ListOfEdges & graph) 50 | : Components(Graph::LOE2CL(graph)) 51 | { 52 | } 53 | 54 | size_t Components::GetCount() const 55 | { 56 | return m_components.size(); 57 | } 58 | 59 | std::vector Components::GetComponent(int index) const 60 | { 61 | return m_components[index]; 62 | } 63 | 64 | Matrix Components::GetComponents() const 65 | { 66 | return m_components; 67 | } 68 | 69 | 70 | 71 | } 72 | 73 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/CutPoints.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | void CutPoints::dfs(const ConnectionList& graph, int v, int p) 6 | { 7 | m_used[v] = true; 8 | m_time_in[v] = m_f_up[v] = ++m_timer; 9 | 10 | int childs = 0; 11 | for (int i = 0; i < graph[v].size(); ++i) 12 | { 13 | int to = graph[v][i].to; 14 | if (to == p) 15 | { 16 | continue; 17 | } 18 | if (m_used[to]) 19 | { 20 | m_f_up[v] = min(m_f_up[v], m_time_in[to]); 21 | } 22 | else 23 | { 24 | dfs(graph, to, v); 25 | m_f_up[v] = min(m_f_up[v], m_f_up[to]); 26 | if (m_f_up[to] >= m_time_in[v] && p != -1) 27 | { 28 | m_cut_points.push_back(v); 29 | } 30 | ++childs; 31 | } 32 | } 33 | if (p == -1 && childs > 1) 34 | { 35 | m_cut_points.push_back(v); 36 | } 37 | } 38 | 39 | CutPoints::CutPoints(const Graph& graph) 40 | : CutPoints(graph.AsConnectionList()) 41 | { 42 | } 43 | 44 | CutPoints::CutPoints(const ConnectionList& graph) 45 | : m_timer(0) 46 | , m_time_in(graph.size()) 47 | , m_used(graph.size()) 48 | , m_f_up(graph.size()) 49 | { 50 | dfs(graph); 51 | std::sort(m_cut_points.begin(), m_cut_points.end()); 52 | auto iter = std::unique(m_cut_points.begin(), m_cut_points.end()); 53 | m_cut_points.erase(iter, m_cut_points.end()); 54 | 55 | } 56 | 57 | CutPoints::CutPoints(const ConnectionMatrix& graph) 58 | : CutPoints(Graph::CM2CL(graph)) 59 | { 60 | } 61 | 62 | CutPoints::CutPoints(const ListOfEdges& graph) 63 | : CutPoints(Graph::LOE2CL(graph)) 64 | { 65 | } 66 | std::vector CutPoints::Get() const 67 | { 68 | return m_cut_points; 69 | } 70 | } -------------------------------------------------------------------------------- /Algorithms/src/Graph/CycleChecker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | namespace algo 4 | { 5 | bool 6 | CycleChecker::dfs 7 | (const ConnectionList & graph, int vertex) 8 | { 9 | m_vertices_state[vertex] = VertexState::Visited; 10 | for (size_t i = 0; i < graph[vertex].size(); ++i) 11 | { 12 | int to = graph[vertex][i].to; 13 | if (m_vertices_state[to] == VertexState::NotVisited) 14 | { 15 | m_parents[to] = vertex; 16 | if (dfs(graph, to)) 17 | { 18 | return true; 19 | } 20 | } 21 | else if (m_vertices_state[to] == VertexState::Visited) 22 | { 23 | m_cycle_start = to; 24 | m_cycle_end = vertex; 25 | return true; 26 | } 27 | } 28 | m_vertices_state[vertex] = VertexState::Exited; 29 | return false; 30 | } 31 | 32 | CycleChecker::CycleChecker(const Graph& graph) 33 | : CycleChecker(graph.AsConnectionList()) 34 | { 35 | } 36 | 37 | CycleChecker::CycleChecker 38 | (const ConnectionList & graph) 39 | : m_vertices_state(graph.size(), VertexState::NotVisited) 40 | , m_cycle_start(-1) 41 | , m_cycle_end(-1) 42 | , m_parents(graph.size(), -1) 43 | , m_cycle_found(false) 44 | , m_cycle(0) 45 | { 46 | for (size_t i = 0; i < graph.size(); i++) 47 | { 48 | if (m_vertices_state[i] == VertexState::NotVisited && 49 | dfs(graph, i)) 50 | { 51 | m_cycle_found = true; 52 | for (int v = m_cycle_end; v != m_cycle_start; v = m_parents[v]) 53 | { 54 | m_cycle.push_back(v); 55 | } 56 | m_cycle.push_back(m_cycle_start); 57 | std::reverse(m_cycle.begin(), m_cycle.end()); 58 | break; 59 | } 60 | } 61 | } 62 | 63 | CycleChecker::CycleChecker 64 | (const ConnectionMatrix & graph) 65 | : CycleChecker(Graph::CM2CL(graph)) 66 | { 67 | } 68 | 69 | CycleChecker::CycleChecker 70 | (const ListOfEdges & graph) 71 | : CycleChecker(Graph::LOE2CL(graph)) 72 | { 73 | } 74 | 75 | bool CycleChecker::HasCycle() const 76 | { 77 | return m_cycle_found; 78 | } 79 | 80 | std::vector CycleChecker::GetCycle() const 81 | { 82 | return m_cycle; 83 | } 84 | 85 | 86 | } 87 | 88 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/DSU.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | 6 | DSU::DSU(int number_of_elements) 7 | : m_parent(number_of_elements) 8 | , m_size(number_of_elements) 9 | { 10 | for (size_t i = 0; i < m_parent.size(); ++i) 11 | { 12 | m_parent[i] = i; 13 | m_size[i] = 1; 14 | } 15 | } 16 | 17 | DSU::Vertex DSU::GetParent(DSU::Vertex vertex) 18 | { 19 | return m_parent[vertex] == vertex 20 | ? vertex 21 | : m_parent[vertex] = GetParent(m_parent[vertex]); 22 | } 23 | 24 | void DSU::Union(DSU::Vertex first, DSU::Vertex second) 25 | { 26 | first = GetParent(first); 27 | second = GetParent(second); 28 | if (first != second) 29 | { 30 | if (m_size[first] > m_size[second]) 31 | { 32 | std::swap(first, second); 33 | } 34 | m_parent[first] = second; 35 | m_size[second] += m_size[first]; 36 | } 37 | 38 | } 39 | 40 | int DSU::MakeNewSet() 41 | { 42 | m_parent.push_back(m_parent.size()); 43 | m_size.push_back(1); 44 | return m_parent.size() - 1; 45 | } 46 | 47 | std::vector DSU::GetGroup(DSU::Vertex element) 48 | { 49 | std::vector group; 50 | element = GetParent(element); 51 | for (size_t i = 0; i < m_parent.size(); ++i) 52 | { 53 | if (GetParent(i) == element) 54 | { 55 | group.push_back(i); 56 | } 57 | } 58 | return group; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include"Graph/Dijkstra.h" 2 | #include"Defines.h" 3 | namespace algo 4 | { 5 | Dijkstra::Dijkstra(const Graph& graph, int start_vertex) 6 | : Dijkstra(graph.AsConnectionList(), start_vertex) 7 | { 8 | } 9 | Dijkstra::Dijkstra 10 | (const Dijkstra::ConnectionList & graph, 11 | int start_vertex) 12 | : m_start_vertex(start_vertex) 13 | { 14 | assert(start_vertex < (int)graph.size()); 15 | 16 | m_distance.resize(graph.size(), Inf); 17 | m_distance[start_vertex] = 0; 18 | m_parents.resize(graph.size()); 19 | for (size_t i = 0; i < m_parents.size(); ++i) 20 | { 21 | m_parents[i] = (int)i; 22 | } 23 | std::set> queue; 24 | queue.emplace(0, start_vertex); 25 | while (!queue.empty()) 26 | { 27 | int from = queue.begin()->second; 28 | queue.erase(queue.begin()); 29 | 30 | for (size_t i = 0; i < graph[from].size(); ++i) 31 | { 32 | int to = graph[from][i].to; 33 | Graph::WeightType weight = graph[from][i].weight; 34 | 35 | if (m_distance[from] + weight < m_distance[to]) 36 | { 37 | queue.erase({ m_distance[to], to }); 38 | m_distance[to] = m_distance[from] + weight; 39 | m_parents[to] = from; 40 | queue.insert({ m_distance[to], to }); 41 | } 42 | } 43 | } 44 | } 45 | 46 | Dijkstra::Dijkstra 47 | (const Dijkstra::ConnectionMatrix& graph, 48 | int start_vertex) 49 | : m_start_vertex(start_vertex) 50 | { 51 | m_distance.resize(graph.size(), Inf); 52 | m_distance[start_vertex] = 0; 53 | m_parents.resize(graph.size()); 54 | for (size_t i = 0; i < m_parents.size(); ++i) 55 | { 56 | m_parents[i] = (int)i; 57 | } 58 | std::vector used(graph.size()); 59 | for (size_t i = 0; i < graph.size(); ++i) 60 | { 61 | size_t v = 0; 62 | bool first_choose = true; 63 | for (size_t j = 0; j < graph[i].size(); ++j) 64 | { 65 | if (!used[j] && (first_choose || 66 | m_distance[j] < m_distance[v])) 67 | { 68 | v = j; 69 | first_choose = false; 70 | } 71 | } 72 | if (m_distance[v] == Inf) 73 | break; 74 | 75 | used[v] = true; 76 | 77 | for (size_t j = 0; j < graph[i].size(); ++i) 78 | { 79 | size_t to = j; 80 | Graph::WeightType weight = graph[i][j]; 81 | if (m_distance[to] > m_distance[v] + weight) 82 | { 83 | m_distance[to] = m_distance[v] + weight; 84 | m_parents[to] = (int)v; 85 | } 86 | } 87 | } 88 | } 89 | 90 | Dijkstra::Dijkstra 91 | (const Dijkstra::ListOfEdges& graph, 92 | int start_vertex) : Dijkstra(Graph::LOE2CL(graph), start_vertex) 93 | { 94 | } 95 | 96 | Graph::WeightType 97 | Dijkstra::GetDistance 98 | (int to) const 99 | { 100 | assert(to < (int)m_distance.size()); 101 | return m_distance[to]; 102 | } 103 | 104 | std::vector 105 | Dijkstra::GetDistance 106 | () const 107 | { 108 | return m_distance; 109 | } 110 | 111 | 112 | std::vector 113 | Dijkstra::GetPath 114 | (int to) const 115 | { 116 | assert(to < (int)m_parents.size()); 117 | std::vector path; 118 | if (to == m_parents[to]) 119 | { 120 | return path; 121 | } 122 | for (int v = to; v != m_start_vertex; v = m_parents[v]) 123 | { 124 | path.push_back(v); 125 | } 126 | path.push_back(m_start_vertex); 127 | std::reverse(all(path)); 128 | return path; 129 | } 130 | 131 | } 132 | 133 | 134 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/Euler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | namespace algo 4 | { 5 | void Euler::dfs (const ConnectionList & graph, int vertex) 6 | { 7 | for (size_t i = 0; i < graph[vertex].size(); ++i) 8 | { 9 | int to = graph[vertex][i].to; 10 | if (m_used.find({ vertex, to }) != m_used.end()) 11 | { 12 | continue; 13 | } 14 | m_used.insert({ vertex, to }); 15 | m_used.insert({ to, vertex }); 16 | dfs(graph, to); 17 | } 18 | m_cycle.push_back(vertex); 19 | } 20 | 21 | Euler::Euler(const Graph& graph) 22 | : Euler(graph.AsConnectionList()) 23 | { 24 | } 25 | 26 | Euler::Euler(const ConnectionList & graph) 27 | : m_has_path(false) 28 | , m_has_cycle(false) 29 | , m_cycle(0) 30 | { 31 | std::vector odd_vertexes; 32 | for (size_t i = 0; i < graph.size(); i++) 33 | { 34 | if (graph[i].size() & 1) 35 | { 36 | if (odd_vertexes.size() == 2) 37 | { 38 | return; 39 | } 40 | odd_vertexes.push_back(i); 41 | } 42 | } 43 | m_has_path = true; 44 | if (!odd_vertexes.size()) 45 | { 46 | m_has_cycle = true; 47 | odd_vertexes.push_back(0); // for determenistic 48 | } 49 | dfs(graph, odd_vertexes[0]); 50 | m_used.clear(); 51 | } 52 | 53 | Euler::Euler 54 | (const ConnectionMatrix & graph) 55 | : Euler(Graph::CM2CL(graph)) 56 | { 57 | } 58 | 59 | Euler::Euler 60 | (const ListOfEdges & graph) 61 | : Euler(Graph::LOE2CL(graph)) 62 | { 63 | } 64 | 65 | bool Euler::HasCycle() const 66 | { 67 | return m_has_cycle; 68 | } 69 | bool Euler::HasPath() const 70 | { 71 | return m_has_path; 72 | } 73 | 74 | std::vector Euler::GetCycle() const 75 | { 76 | return m_cycle; 77 | } 78 | 79 | 80 | } 81 | 82 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/FloydWarshall.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph/FloydWarshall.h" 2 | 3 | namespace algo 4 | { 5 | FloydWarshall::FloydWarshall 6 | (const Graph& graph) 7 | : FloydWarshall(graph.AsConnectionMatrix()) 8 | { 9 | } 10 | FloydWarshall::FloydWarshall 11 | (const ConnectionList & connection_list) 12 | : FloydWarshall(Graph::CL2CM(connection_list)) 13 | { 14 | } 15 | 16 | FloydWarshall::FloydWarshall 17 | (const ConnectionMatrix & connection_matrix) 18 | { 19 | m_distances = connection_matrix; 20 | size_t matrix_size = connection_matrix.size(); 21 | m_parents = CreateMatrix(matrix_size, matrix_size, -1); 22 | for (size_t i = 0; i < matrix_size; ++i) 23 | { 24 | for (size_t j = 0; j < matrix_size; ++j) 25 | { 26 | if (connection_matrix[i][j]) 27 | { 28 | m_parents[i][j] = (int)j; 29 | } 30 | else 31 | { 32 | if (i != j) 33 | { 34 | m_distances[i][j] = Inf; 35 | } 36 | } 37 | } 38 | m_parents[i][i] = (int)i; 39 | } 40 | for (size_t k = 0; k < matrix_size; ++k) 41 | { 42 | for (size_t i = 0; i < matrix_size; ++i) 43 | { 44 | for (size_t j = 0; j < matrix_size; ++j) 45 | { 46 | if (m_distances[i][k] == Inf || 47 | m_distances[k][j] == Inf) 48 | { 49 | continue; 50 | } 51 | WeightType weight = 52 | m_distances[i][k] + m_distances[k][j]; 53 | if (m_distances[i][j] > weight) 54 | { 55 | m_distances[i][j] = weight; 56 | m_parents[i][j] = m_parents[i][k]; 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | FloydWarshall::FloydWarshall 64 | (const ListOfEdges & list_of_edges) 65 | : FloydWarshall(Graph::LOE2CM(list_of_edges)) 66 | { 67 | } 68 | 69 | FloydWarshall::WeightType 70 | FloydWarshall::GetDistance 71 | (int from, int to) const 72 | 73 | { 74 | return m_distances[from][to]; 75 | } 76 | 77 | std::vector 78 | FloydWarshall::GetDistance 79 | (int from) const 80 | { 81 | return m_distances[from]; 82 | } 83 | 84 | std::vector 85 | FloydWarshall::GetPath 86 | (int from, int to) const 87 | { 88 | /* std::vector path; 89 | if (from == to) 90 | return path; 91 | get_path(from, to, path); 92 | return path;*/ 93 | std::vector path; 94 | if (m_parents[from][to] == -1) 95 | return path; 96 | if (from == to) 97 | return path; 98 | path.push_back(from); 99 | while (to != from) 100 | { 101 | from = m_parents[from][to]; 102 | path.push_back(from); 103 | } 104 | return path; 105 | } 106 | void 107 | FloydWarshall::get_path 108 | (int from, int to, std::vector& path) 109 | { 110 | if (from == to) 111 | { 112 | path.push_back(from); 113 | } 114 | else if (m_parents[from][to] == -1) 115 | { 116 | path.clear(); 117 | return; 118 | } 119 | else 120 | { 121 | get_path(from, m_parents[from][to], path); 122 | path.push_back(to); 123 | } 124 | /*std::vector path; 125 | if(m_parents[from][to] == -1) 126 | return path; 127 | path.push_back(to); 128 | while (to != from) 129 | { 130 | to = m_parents[from][to]; 131 | path.push_back(to); 132 | } 133 | return path;*/ 134 | } 135 | 136 | } 137 | 138 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/FordBellman.cpp: -------------------------------------------------------------------------------- 1 | #include"Graph/FordBellman.h" 2 | #include"Defines.h" 3 | namespace algo 4 | { 5 | FordBellman::FordBellman(const Graph & graph, int start_vertex) 6 | : FordBellman(graph.AsListOfEdges(), start_vertex) 7 | { 8 | } 9 | FordBellman::FordBellman(const ConnectionList & graph, int start_vertex) 10 | : FordBellman(Graph::CL2LOE(graph), start_vertex) 11 | { 12 | } 13 | FordBellman::FordBellman(const ConnectionMatrix & graph, int start_vertex) 14 | : FordBellman(Graph::CM2LOE(graph), start_vertex) 15 | { 16 | } 17 | FordBellman::FordBellman(const ListOfEdges & graph, int start_vertex) 18 | : n(Graph::GetSize(graph)) 19 | , m_parents(n, -1) 20 | , m_distance(n, Inf) 21 | { 22 | m_distance[start_vertex] = 0; 23 | bool any = true; 24 | while(any) 25 | { 26 | any = false; 27 | for (int j = 0; j < graph.size(); ++j) 28 | { 29 | if (m_distance[graph[j].from] < Inf) 30 | { 31 | Graph::WeightType& to_dist = m_distance[graph[j].to]; 32 | Graph::WeightType from_dist = m_distance[graph[j].from] + 33 | graph[j].weight; 34 | if (to_dist > from_dist) 35 | { 36 | to_dist = from_dist; 37 | m_parents[graph[j].to] = graph[j].from; 38 | any = true; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | Graph::WeightType FordBellman::GetDistance(int to) const 45 | { 46 | return m_distance[to]; 47 | } 48 | std::vector FordBellman::GetDistance() const 49 | { 50 | return m_distance; 51 | } 52 | std::vector algo::FordBellman::GetPath(int to) const 53 | { 54 | if (m_distance[to] == Inf) 55 | return {}; 56 | std::vector path; 57 | if (m_parents[to] == -1) 58 | { 59 | return path; 60 | } 61 | for (int cur = to; cur != -1; cur = m_parents[cur]) 62 | path.push_back(cur); 63 | reverse(path.begin(), path.end()); 64 | return path; 65 | } 66 | } -------------------------------------------------------------------------------- /Algorithms/src/Graph/Khun.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | bool Khun::dfs(const ConnectionList& graph, int v) 6 | { 7 | return false; 8 | } 9 | Khun::Khun(const Graph& graph) 10 | { 11 | } 12 | Khun::Khun(const ConnectionList& graph) 13 | { 14 | } 15 | Khun::Khun(const ConnectionMatrix& graph) 16 | { 17 | } 18 | Khun::Khun(const ListOfEdges& graph) 19 | { 20 | } 21 | std::vector Khun::Get() const 22 | { 23 | return std::vector(); 24 | } 25 | } -------------------------------------------------------------------------------- /Algorithms/src/Graph/Kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | Kruskal::Kruskal(const Graph& graph) 6 | : Kruskal(graph.AsListOfEdges()) 7 | { 8 | } 9 | Kruskal::Kruskal(const ConnectionList & graph) 10 | : Kruskal(Graph::CL2LOE(graph)) 11 | { 12 | } 13 | Kruskal::Kruskal(const ConnectionMatrix & graph) 14 | : Kruskal(Graph::CM2LOE(graph)) 15 | { 16 | } 17 | Kruskal::Kruskal(const ListOfEdges& graph) 18 | : m_dsu(Graph::GetSize(graph)) 19 | , m_cost(0) 20 | { 21 | std::set 22 | all_edges(graph.begin(), graph.end()); 23 | 24 | size_t number_of_edges = graph.size(); 25 | for (size_t i = 0; i < number_of_edges; ++i) 26 | { 27 | Graph::Edge e = *all_edges.begin(); 28 | all_edges.erase(all_edges.begin()); 29 | Graph::VertexType from = e.from; 30 | Graph::VertexType to = e.to; 31 | Graph::WeightType weight = e.weight; 32 | 33 | if (m_dsu.GetParent(from) != m_dsu.GetParent(to)) 34 | { 35 | m_cost += weight; 36 | m_spanning_tree.push_back(e); 37 | m_dsu.Union(from, to); 38 | } 39 | } 40 | std::sort(m_spanning_tree.begin(), m_spanning_tree.end()); 41 | } 42 | std::vector Kruskal::GetTree() const 43 | { 44 | return m_spanning_tree; 45 | } 46 | Graph::WeightType Kruskal::GetCost() const 47 | { 48 | return m_cost; 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph\LCA.h" 2 | namespace algo 3 | { 4 | 5 | void LCA::dfs(const ConnectionList& graph, int vertex, int prev) 6 | { 7 | m_time_in[vertex] = ++m_timer; 8 | m_up[vertex][0] = prev; 9 | for (int i = 1; i < m_up[vertex].size(); ++i) 10 | { 11 | m_up[vertex][i] = m_up[m_up[vertex][i - 1]][i - 1]; 12 | } 13 | for (int i = 0; i < graph[vertex].size(); ++i) 14 | { 15 | int to = graph[vertex][i].to; 16 | if (to != prev) 17 | { 18 | dfs(graph, to, vertex); 19 | } 20 | } 21 | m_time_out[vertex] = ++m_timer; 22 | } 23 | 24 | bool LCA::upper(int a, int b) const 25 | { 26 | return m_time_in[a] <= m_time_in[b] && 27 | m_time_out[a] >= m_time_out[b]; 28 | } 29 | 30 | int LCA::greater_power_of_2(int n) 31 | { 32 | int power = 1; 33 | while ((1 << power) <= n) 34 | { 35 | ++power; 36 | } 37 | return power + 1; 38 | } 39 | 40 | LCA::LCA(const Graph& graph) 41 | : LCA(graph.AsConnectionList()) 42 | { 43 | } 44 | 45 | LCA::LCA(const ConnectionList& graph) 46 | : m_up(graph.size(),std::vector(greater_power_of_2(graph.size()))) 47 | , m_time_in(graph.size()) 48 | , m_time_out(graph.size()) 49 | , m_timer(0) 50 | { 51 | dfs(graph); 52 | } 53 | 54 | LCA::LCA(const ConnectionMatrix& graph) 55 | : LCA(Graph::CM2CL(graph)) 56 | { 57 | } 58 | 59 | LCA::LCA(const ListOfEdges& graph) 60 | : LCA(Graph::LOE2CL(graph)) 61 | { 62 | } 63 | int LCA::Get(int a, int b) const 64 | { 65 | if (upper(a, b)) 66 | return a; 67 | if (upper(b, a)) 68 | return b; 69 | for (int i = m_up[a].size() - 1; i >= 0; --i) 70 | { 71 | if (!upper(m_up[a][i], b)) 72 | { 73 | a = m_up[a][i]; 74 | } 75 | } 76 | return m_up[a][0]; 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/PruferCode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | namespace algo 4 | { 5 | PruferCode::PruferCode() 6 | { 7 | } 8 | std::vector PruferCode::Encode(const Graph& graph) 9 | { 10 | auto connection_list = graph.AsConnectionList(); 11 | std::vector> g(connection_list.size()); 12 | for (int i = 0; i < g.size(); ++i) 13 | { 14 | g[i].insert(connection_list[i].begin(), connection_list[i].end()); 15 | } 16 | std::set> degs; 17 | for (int i = 0; i < g.size(); ++i) 18 | { 19 | degs.insert({ g[i].size(), i }); 20 | } 21 | std::vector used(g.size()); 22 | std::vector code; 23 | while (degs.size() > 2) 24 | { 25 | int from = degs.begin()->second; 26 | degs.erase(degs.begin()); 27 | int to = g[from].begin()->to; 28 | g[from].erase(g[from].begin()); 29 | g[to].erase(g[to].find(Graph::Edge{ to, from })); 30 | code.push_back(to); 31 | degs.erase(degs.find({ g[to].size() + 1, to })); 32 | degs.insert({ g[to].size(), to }); 33 | } 34 | return code; 35 | } 36 | Graph PruferCode::Decode(const std::vector& code) 37 | { 38 | return Graph(Graph::ConnectionList{ {} }); 39 | } 40 | } -------------------------------------------------------------------------------- /Algorithms/src/Graph/StrongComponents.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph\StrongComponents.h" 2 | #include "Graph\Toposort.h" 3 | 4 | 5 | namespace algo 6 | { 7 | void StrongComponents::dfs(const ConnectionList & graph, int vertex) 8 | { 9 | m_used[vertex] = true; 10 | m_components.back().push_back(vertex); 11 | for (auto& neighbours : graph[vertex]) 12 | { 13 | if (!m_used[neighbours.to]) 14 | { 15 | dfs(graph, neighbours.to); 16 | } 17 | } 18 | } 19 | StrongComponents::StrongComponents(const Graph& graph) 20 | : StrongComponents(graph.AsConnectionList()) 21 | { 22 | } 23 | StrongComponents::StrongComponents(const ConnectionList & graph) 24 | : m_used(Graph::GetSize(graph)) 25 | { 26 | Toposort toposort(graph); 27 | auto sorted_vertices = toposort.GetNewVerticesIndices(); 28 | 29 | ConnectionList reversed_graph = Graph::Reverse(graph); 30 | 31 | size_t graph_size = Graph::GetSize(graph); 32 | 33 | for (size_t i = 0; i < graph_size; i++) 34 | { 35 | if (!m_used[sorted_vertices[i]]) 36 | { 37 | m_components.push_back({}); 38 | dfs(reversed_graph, sorted_vertices[i]); 39 | } 40 | } 41 | for (auto& component : m_components) 42 | { 43 | std::sort(component.begin(), component.end()); 44 | } 45 | std::sort(m_components.begin(), m_components.end()); 46 | } 47 | 48 | StrongComponents::StrongComponents(const ConnectionMatrix & graph) 49 | : StrongComponents(Graph::CM2CL(graph)) 50 | { 51 | } 52 | 53 | StrongComponents::StrongComponents(const ListOfEdges & graph) 54 | : StrongComponents(Graph::LOE2CM(graph)) 55 | { 56 | } 57 | 58 | int StrongComponents::GetCount() const 59 | { 60 | return m_components.size(); 61 | } 62 | 63 | std::vector 64 | StrongComponents::GetComponent(int index) const 65 | { 66 | return m_components[index]; 67 | } 68 | 69 | Matrix 70 | StrongComponents::GetComponents() const 71 | { 72 | return m_components; 73 | } 74 | 75 | 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /Algorithms/src/Graph/Toposort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | namespace algo 6 | { 7 | void Toposort::dfs(const ConnectionList & graph, int vertex) 8 | { 9 | m_used[vertex] = true; 10 | for (size_t i = 0; i < graph[vertex].size(); ++i) 11 | { 12 | int to = graph[vertex][i].to; 13 | if (!m_used[to]) 14 | { 15 | dfs(graph, to); 16 | } 17 | } 18 | m_sorted_vertices.push_back(vertex); 19 | } 20 | 21 | Toposort::Toposort(const Graph& graph) 22 | : Toposort(graph.AsConnectionList()) 23 | { 24 | } 25 | 26 | Toposort::Toposort(const ConnectionList & graph) 27 | : m_sorted_vertices(0) 28 | , m_used(graph.size()) 29 | { 30 | /*CycleChecker cycle_checker(graph); 31 | if (cycle_checker.HasCycle()) 32 | { 33 | throw std::logic_error("Graph must be acyclic for toposort"); 34 | }*/ 35 | for (size_t i = 0; i < m_used.size(); ++i) 36 | { 37 | if (!m_used[i]) 38 | { 39 | dfs(graph, i); 40 | } 41 | } 42 | std::reverse(m_sorted_vertices.begin(), m_sorted_vertices.end()); 43 | } 44 | 45 | Toposort::Toposort(const ConnectionMatrix & graph) 46 | : Toposort(Graph::CM2CL(graph)) 47 | { 48 | } 49 | Toposort::Toposort(const ListOfEdges & graph) 50 | : Toposort(Graph::LOE2CL(graph)) 51 | { 52 | } 53 | std::vector Toposort::GetNewVerticesIndices() const 54 | { 55 | return m_sorted_vertices; 56 | } 57 | } 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Algorithms/src/Math/Math.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | namespace algo 5 | { 6 | int euler_function(int n) 7 | { 8 | int ans = 0; 9 | for (int i = 1; i <= n; ++i) 10 | { 11 | ans += gcd(i, n) == 1; 12 | } 13 | return ans; 14 | } 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /Algorithms/src/Strings/KnuthMorrisPratt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | void KnuthMorrisPratt::calculate() 6 | { 7 | auto prefix = m_prefix.Get(); 8 | for (int i = m_first_size + 1; i < prefix.size(); ++i) 9 | { 10 | if (prefix[i] == m_first_size) 11 | { 12 | m_occurs.push_back(i - 2 * m_first_size); 13 | } 14 | } 15 | } 16 | KnuthMorrisPratt::KnuthMorrisPratt(const std::string& where, 17 | const std::string& what) 18 | : m_prefix(what + "#" + where) 19 | , m_first_size(what.size()) 20 | { 21 | calculate(); 22 | } 23 | std::vector KnuthMorrisPratt::Get() const 24 | { 25 | return m_occurs; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Algorithms/src/Strings/PrefixFunction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | namespace algo 4 | { 5 | void PrefixFunction::calculate() 6 | { 7 | for (int i = 1; i < m_str.size(); ++i) 8 | { 9 | int j = m_prefix[i - 1]; 10 | while (j > 0 && m_str[i] != m_str[j]) 11 | { 12 | j = m_prefix[j - 1]; 13 | } 14 | if (m_str[i] == m_str[j]) 15 | { 16 | ++j; 17 | } 18 | m_prefix[i] = j; 19 | } 20 | } 21 | 22 | PrefixFunction::PrefixFunction(const std::string& str) 23 | : m_str(str) 24 | , m_prefix(str.size()) 25 | { 26 | calculate(); 27 | } 28 | 29 | std::vector PrefixFunction::Get() const 30 | { 31 | return m_prefix; 32 | } 33 | 34 | 35 | } -------------------------------------------------------------------------------- /Algorithms/src/Strings/StringHashing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace algo 4 | { 5 | void StringHashing::build_hash() 6 | { 7 | m_primes[0] = 1; 8 | for (int i = 0; i < m_str.size(); ++i) 9 | { 10 | m_hashes[i + 1] = m_hashes[i] * m_prime + m_str[i]; 11 | m_hashes[i + 1] %= m_mod; 12 | m_primes[i + 1] = m_primes[i] * m_prime; 13 | m_primes[i + 1] %= m_mod; 14 | } 15 | } 16 | StringHashing::StringHashing(const std::string& str, StringHashing::HashType mod) 17 | : m_str(str) 18 | , m_hashes(str.size() + 1) 19 | , m_primes(str.size() + 1) 20 | , m_mod(mod) 21 | { 22 | build_hash(); 23 | } 24 | StringHashing::HashType StringHashing::Get() const 25 | { 26 | return Get(0, m_str.size() - 1); 27 | } 28 | StringHashing::HashType StringHashing::Get(int i, int j) const 29 | { 30 | HashType hash = m_hashes[j + 1]; 31 | hash -= (m_hashes[i] * m_primes[j - i + 1]) % m_mod; 32 | if (hash < 0) 33 | hash += m_mod; 34 | return hash; 35 | } 36 | std::size_t StringHashing::Size() const 37 | { 38 | return m_str.size(); 39 | } 40 | } -------------------------------------------------------------------------------- /Algorithms/src/Strings/ZFunction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | namespace algo 4 | { 5 | void Z_Function::calculate() 6 | { 7 | for (int i = 1, l = 0, r = 0; i < m_str.size(); ++i) 8 | { 9 | if (i <= r) 10 | { 11 | m_z[i] = std::min(r - i + 1, m_z[i - l]); 12 | } 13 | while (i + m_z[i] < m_str.size() && 14 | m_str[i + m_z[i]] == m_str[m_z[i]]) 15 | { 16 | ++m_z[i]; 17 | } 18 | if (i + m_z[i] - 1 > r) 19 | { 20 | l = i; 21 | r = i + m_z[i] - 1; 22 | } 23 | } 24 | } 25 | 26 | Z_Function::Z_Function(const std::string& str) 27 | : m_str(str) 28 | , m_z(str.size()) 29 | { 30 | calculate(); 31 | } 32 | 33 | std::vector Z_Function::Get() const 34 | { 35 | return m_z; 36 | } 37 | 38 | 39 | } -------------------------------------------------------------------------------- /CodePreprocessor/CodePreprocessor.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {CCB2C8E4-44A5-4731-9556-79CF4A514A06} 24 | CodePreprocessor 25 | 10.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v142 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | true 79 | true 80 | 81 | 82 | 83 | 84 | Level3 85 | Disabled 86 | true 87 | true 88 | 89 | 90 | 91 | 92 | Level3 93 | MaxSpeed 94 | true 95 | true 96 | true 97 | true 98 | 99 | 100 | true 101 | true 102 | 103 | 104 | 105 | 106 | Level3 107 | MaxSpeed 108 | true 109 | true 110 | true 111 | true 112 | 113 | 114 | true 115 | true 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /CodePreprocessor/CodePreprocessor.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Resource Files 23 | 24 | 25 | Resource Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /CodePreprocessor/FileProcessor.cpp: -------------------------------------------------------------------------------- 1 | #include "FileProcessor.h" 2 | #include "FileSearcher.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | FileProcessor::FileProcessor(const std::wstring& file_path, 8 | const std::vector& folder_paths) 9 | : mp_file_searcher(new FileSearcher(folder_paths)) 10 | , m_file_path(file_path) 11 | { 12 | if (!FileSearcher::CheckFileValidity(m_file_path)) 13 | { 14 | throw std::logic_error("Source file failed to open"); 15 | } 16 | } 17 | 18 | void FileProcessor::Process() const 19 | { 20 | std::wstring output_file_name = m_file_path; 21 | std::size_t pos_of_last_dot = output_file_name.find_last_of(L'.'); 22 | output_file_name.insert(pos_of_last_dot, L"_processed"); 23 | std::wofstream out_file(output_file_name); 24 | 25 | std::stack files_to_process; 26 | files_to_process.emplace(m_file_path); 27 | std::wregex reg(L"#include\\s*[<\"](.*)[\">].*"); 28 | 29 | std::set processed_files; 30 | processed_files.insert(m_file_path); 31 | 32 | while (!files_to_process.empty()) 33 | { 34 | std::wifstream& ifs = files_to_process.top(); 35 | std::wstring line; 36 | if (!std::getline(ifs, line)) 37 | { 38 | files_to_process.pop(); 39 | continue; 40 | } 41 | std::wsmatch sm; 42 | std::regex_match(line, sm, reg); 43 | if (sm.empty()) 44 | { 45 | out_file << line << std::endl; 46 | continue; 47 | } 48 | std::wstring h_name = sm[1]; 49 | std::replace(std::begin(h_name), 50 | std::end(h_name), 51 | L'\\', L'/'); 52 | std::wstring h_path = mp_file_searcher->CheckForFile(h_name); 53 | if (!h_path.empty()) 54 | { 55 | if (h_path.back() == L'h') 56 | { 57 | std::wstring cpp_name = h_name; 58 | cpp_name.pop_back(); 59 | cpp_name += L"cpp"; 60 | std::wstring cpp_path = 61 | mp_file_searcher->CheckForFile(cpp_name); 62 | 63 | if (!cpp_path.empty()) 64 | { 65 | auto file_processed_it = processed_files.find(cpp_path); 66 | if (file_processed_it == processed_files.end()) 67 | { 68 | files_to_process.emplace(cpp_path); 69 | processed_files.insert(cpp_path); 70 | } 71 | } 72 | } 73 | if (processed_files.find(h_path) == processed_files.end()) 74 | { 75 | files_to_process.emplace(h_path); 76 | processed_files.insert(h_path); 77 | } 78 | } 79 | else 80 | { 81 | out_file << line << std::endl; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /CodePreprocessor/FileProcessor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | class FileSearcher; 6 | 7 | class FileProcessor 8 | { 9 | std::shared_ptr mp_file_searcher; 10 | std::wstring m_file_path; 11 | public: 12 | 13 | FileProcessor(const std::wstring& file_name, 14 | const std::vector& folder_paths); 15 | void Process() const; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /CodePreprocessor/FileSearcher.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "FileSearcher.h" 3 | #include 4 | bool FileSearcher::CheckFileValidity(const std::wstring& filename) 5 | { 6 | std::ifstream ifs; 7 | ifs.open(filename); 8 | return ifs.is_open(); 9 | } 10 | FileSearcher::FileSearcher(const std::vector& folder_paths) 11 | : m_folder_paths(folder_paths) 12 | { 13 | for (auto& folder_path : m_folder_paths) 14 | { 15 | // Replacing all slashes by backslashes 16 | std::replace(std::begin(folder_path), 17 | std::end(folder_path), 18 | L'\\', L'/'); 19 | 20 | if (folder_path == L"/") // case of root in POSIX 21 | { 22 | continue; 23 | } 24 | while (folder_path.size() && folder_path.back() == L'/') 25 | { 26 | folder_path.pop_back(); 27 | } 28 | } 29 | } 30 | 31 | std::wstring FileSearcher::CheckForFile(const std::wstring & file_name) const 32 | { 33 | for (auto& folder_path : m_folder_paths) 34 | { 35 | std::wstring full_file_path = folder_path + L"/" + file_name; 36 | if (CheckFileValidity(full_file_path)) 37 | { 38 | return full_file_path; 39 | } 40 | } 41 | return L""; 42 | } 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /CodePreprocessor/FileSearcher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class FileSearcher 8 | { 9 | std::vector m_folder_paths; 10 | 11 | public: 12 | static bool CheckFileValidity(const std::wstring& filename); 13 | 14 | public: 15 | FileSearcher(const std::vector& folder_paths); 16 | std::wstring CheckForFile(const std::wstring& file_name) const; 17 | }; -------------------------------------------------------------------------------- /CodePreprocessor/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"FileProcessor.h" 3 | 4 | int wmain(int argc, wchar_t** argv) try 5 | { 6 | std::wstring file_path = argv[1]; 7 | std::vector folder_paths; 8 | for (int i = 2; i < argc; ++i) 9 | { 10 | folder_paths.push_back(argv[i]); 11 | } 12 | FileProcessor file_processor(file_path, folder_paths); 13 | file_processor.Process(); 14 | std::cout << "Code preprocessing is " 15 | << "successfully finished!" 16 | << std::endl; 17 | } 18 | catch (const std::exception& ex) 19 | { 20 | std::cout << ex.what() << std::endl; 21 | } 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /CodePreprocessor/Source_processed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /Coding/Coding.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 15.0 26 | {4BB0180F-DDE9-4172-8518-58FDE5F49D2C} 27 | Win32Proj 28 | Coding 29 | 10.0 30 | 31 | 32 | 33 | Application 34 | true 35 | v142 36 | Unicode 37 | 38 | 39 | Application 40 | false 41 | v142 42 | true 43 | Unicode 44 | 45 | 46 | Application 47 | true 48 | v142 49 | Unicode 50 | 51 | 52 | Application 53 | false 54 | v142 55 | true 56 | Unicode 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | true 78 | $(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath); 79 | C:\Users\Levonog\source\repos\Algorithms\x64\Debug;$(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 80 | 81 | 82 | true 83 | $(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath); 84 | C:\Users\Levonog\source\repos\Algorithms\x64\Debug;$(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 85 | 86 | 87 | false 88 | $(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath); 89 | C:\Users\Levonog\source\repos\Algorithms\x64\Debug;$(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 90 | 91 | 92 | false 93 | $(SolutionDir)\Algorithms\include;$(VC_IncludePath);$(WindowsSDK_IncludePath); 94 | C:\Users\Levonog\source\repos\Algorithms\x64\Debug;$(SolutionDir)$(Configuration)\;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 95 | 96 | 97 | 98 | Level3 99 | Disabled 100 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 101 | true 102 | 103 | 104 | true 105 | Console 106 | Algorithms.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 107 | 108 | 109 | $(SolutionDir)$(Configuration)\CodePreprocessor.exe Source.cpp ..\Algorithms\include ..\Algorithms\src 110 | 111 | 112 | 113 | 114 | Level3 115 | Disabled 116 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 117 | true 118 | 119 | 120 | true 121 | Console 122 | Algorithms.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 123 | 124 | 125 | $(SolutionDir)$(Configuration)\CodePreprocessor.exe Source.cpp ..\Algorithms\include ..\Algorithms\src 126 | 127 | 128 | 129 | 130 | Level3 131 | MaxSpeed 132 | true 133 | true 134 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | true 136 | 137 | 138 | true 139 | true 140 | true 141 | Console 142 | Algorithms.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 143 | 144 | 145 | $(SolutionDir)$(Configuration)\CodePreprocessor.exe Source.cpp ..\Algorithms\include ..\Algorithms\src 146 | 147 | 148 | 149 | 150 | Level3 151 | MaxSpeed 152 | true 153 | true 154 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 155 | true 156 | 157 | 158 | true 159 | true 160 | true 161 | Console 162 | Algorithms.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 163 | 164 | 165 | $(SolutionDir)$(Configuration)\CodePreprocessor.exe Source.cpp ..\Algorithms\include ..\Algorithms\src 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /Coding/Coding.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Coding/Source.cpp: -------------------------------------------------------------------------------- 1 | #pragma comment(linker, "/STACK:200000000") 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | 8 | //struct Config 9 | //{ 10 | // static int battle_mages_count; 11 | // static int heal_mages_count; 12 | //} config; 13 | // 14 | //class Mage 15 | //{ 16 | // // input values 17 | // double _max_value; 18 | // double _increasing_value; 19 | // double _decreasing_value; 20 | // 21 | // // common values 22 | // double _max_hp; 23 | // double _velocity; 24 | // 25 | // // changable values 26 | // double _current_value; 27 | // double _current_hp; 28 | // double _pos_x; 29 | // double _pos_y; 30 | // 31 | //public: 32 | // Mage(double max_hp, double velocity) 33 | // : _pos_x(0) 34 | // , _pos_y(0) 35 | // , _max_hp(max_hp) 36 | // , _velocity(velocity) 37 | // , _current_hp(max_hp) 38 | // , _current_value(0) 39 | // 40 | // , _max_value(-1) 41 | // , _increasing_value(-1) 42 | // , _decreasing_value(-1) 43 | // { 44 | // } 45 | // void IncreaseValue(int msecs) 46 | // { 47 | // this->_current_value += this->_increasing_value * msecs / 1000.0; 48 | // } 49 | // double GetValue() const 50 | // { 51 | // this->_current_value; 52 | // } 53 | // void Move(int msecs) 54 | // { 55 | // // TODO 56 | // } 57 | // double GetDistance(double x, double y) const 58 | // { 59 | // return sqrt((x - this->_pos_x) * (x - this->_pos_x) + (y - this->_pos_x) * (y - this->_pos_y)); 60 | // } 61 | // double GetVelocity() const 62 | // { 63 | // return this->_velocity; 64 | // } 65 | // friend istream& operator>>(istream& is, Mage& mage); 66 | // virtual void DoAction() = 0; 67 | //}; 68 | // 69 | //istream& operator>>(istream& is, Mage& mage) 70 | //{ 71 | // is >> mage._max_value >> mage._increasing_value >> mage._decreasing_value; 72 | //} 73 | // 74 | // 75 | //class DamageMage : public Mage 76 | //{ 77 | //public: 78 | // DamageMage(double max_hp, double velocity) : Mage(max_hp, velocity) {} 79 | // virtual void DoAction() 80 | // { 81 | // // TODO 82 | // } 83 | //}; 84 | // 85 | // 86 | //class HealingMage : public Mage 87 | //{ 88 | //public: 89 | // HealingMage(double max_hp, double velocity) : Mage(max_hp, velocity) {} 90 | // virtual void DoAction() 91 | // { 92 | // // TODO 93 | // } 94 | //}; 95 | // 96 | //class DragonAttack 97 | //{ 98 | // double _power; 99 | // double _duration; 100 | // virtual void input(istream& is) = 0; 101 | //public: 102 | // friend istream& operator>>(istream& is, DragonAttack& attack); 103 | //}; 104 | //istream& operator>>(istream& is, DragonAttack& attack) 105 | //{ 106 | // attack.input(is); 107 | //} 108 | // 109 | //class BreathAttack : public DragonAttack 110 | //{ 111 | // vector _pos_xs; 112 | // vector _pos_ys; 113 | // virtual void input(istream& is) 114 | // { 115 | // int size = config.battle_mages_count + config.heal_mages_count; 116 | // _pos_xs.resize(size); 117 | // _pos_ys.resize(size); 118 | // for (int i = 0; i < size; ++i) 119 | // { 120 | // is >> _pos_xs[i] >> _pos_ys[i]; 121 | // } 122 | // } 123 | //}; 124 | // 125 | //class StormAttack : public DragonAttack 126 | //{ 127 | // double _pos_x; 128 | // double _pos_y; 129 | // virtual void input(istream& is) = 0; 130 | //}; 131 | // 132 | //class TailAttack : public DragonAttack 133 | //{ 134 | // 135 | //}; 136 | // 137 | //class Game 138 | //{ 139 | // 140 | //}; 141 | 142 | #include 143 | #include 144 | #include 145 | 146 | int segment_tree_update(int a, int b) 147 | { 148 | if (a * 1ll * b > 1e5) 149 | { 150 | return 0; 151 | } 152 | return a * b; 153 | } 154 | 155 | void print(int a) 156 | { 157 | // cerr << "----------------------------------" << a << " "; 158 | if (a < 10) 159 | cout << "Slideshow"; 160 | else if (a < 60) 161 | cout << "So-so"; 162 | else 163 | cout << "Perfect"; 164 | cout << endl; 165 | } 166 | 167 | void check(int mult, int t, int h, int w) 168 | { 169 | if (mult == 0) 170 | { 171 | print(0); 172 | } 173 | else 174 | { 175 | print(t / (w * 1ll * h * mult)); 176 | } 177 | } 178 | 179 | int main() 180 | { 181 | unordered_map indices; 182 | int n; 183 | cin >> n; 184 | vector mults(n); 185 | for (int i = 0; i < n; ++i) 186 | { 187 | string s; 188 | cin >> s; 189 | indices[algo::StringHashing(s).Get()] = i; 190 | cin >> mults[i]; 191 | } 192 | algo::SegmentTree tree(mults, segment_tree_update, 1, algo::SegmentTree::UpdateType::Assign); 193 | 194 | int h, w, t; 195 | cin >> h >> w >> t; 196 | 197 | check(tree.query(0, n - 1), t, h, w); 198 | int q; 199 | cin >> q; 200 | for (int i = 0; i < q; ++i) 201 | { 202 | string s; 203 | cin >> s; 204 | if (s == "On") 205 | { 206 | string t; 207 | cin >> t; 208 | int index = indices[algo::StringHashing(t).Get()]; 209 | tree.update(index, mults[index]); 210 | } 211 | else if (s == "Off") 212 | { 213 | string t; 214 | cin >> t; 215 | int index = indices[algo::StringHashing(t).Get()]; 216 | tree.update(index, 1); 217 | } 218 | else 219 | { 220 | cin >> h >> w; 221 | } 222 | check(tree.query(0, n - 1), t, h, w); 223 | } 224 | } -------------------------------------------------------------------------------- /Coding/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms 2 | 3 | This repo is a pretty organized collection of various algorithms implemented using C++17 (Microsoft Visual Studio 2019, but 2017 is also acceptable). 4 | 5 | All algorithms implementations you can find in "Algorithms" folder. 6 | 7 | All algorithms are tested and all the tests you can find in "AlgorithmTests" folder. I'm using googletest. 8 | 9 | Also here is "CodePreprocessor" folder, that simulates C++ preprocessor job, but only for headers of this repo. This preprocessor is works during code compilation and generates postprocessed source, located near original source, that doesn't contain any include of this repo, so it can be submitted to the any online judge. 10 | 11 | I use this repo to learn, remember, and easily use algorithms and I will be very happy if it would help someone too! Do not hesitate to contribute or open new issues! 12 | --------------------------------------------------------------------------------