├── Config ├── makefile ├── sublime │ ├── c++ konsole.sublime-build │ └── cmd.sublime-build └── vs code │ ├── makefile │ └── tasks.json ├── cpp ├── Algebra │ ├── Z2 Vector Space.cpp │ ├── fast_walsh_hadamard_transform.cpp │ ├── fft arbitrary mod using crt.cpp │ ├── fft.cpp │ ├── fft_jtnydv.cpp │ ├── linear equations gauss elimination.cpp │ ├── linear recurrance O(mlog^2n).cpp │ ├── linear recurrance O(n^2logn).cpp │ ├── linear recurrance with BerlekampMassey.cpp │ ├── matrix functions.cpp │ ├── matrixMultiplication.cpp │ ├── ntt+crt.cpp │ ├── ntt.cpp │ ├── online fft recursive.cpp │ ├── online fft.cpp │ ├── polynomial functions jatin yadav.cpp │ ├── polynomial functions.cpp │ ├── polynomial_interpolation.cpp │ ├── simplex.cpp │ ├── strassens.cpp │ └── xor3.cpp ├── Data Structures │ ├── 128bit.cpp │ ├── bigint.cpp │ ├── dsu.cpp │ ├── dsu_with_rollback.cpp │ ├── implicit treap.cpp │ ├── non-overlapping intervals.cpp │ ├── order statistics tree.cpp │ ├── persistent trie.cpp │ ├── rmq.cpp │ ├── segtree with pointers.cpp │ ├── segtree.cpp │ ├── serach_buckets.cpp │ ├── splay tree.cpp │ ├── treap.cpp │ ├── trie without pointer.cpp │ └── umap_hash.cpp ├── Dynamic Programming │ ├── convex hull dp set.cpp │ ├── convex hull dp.cpp │ ├── divide and conquer dp.cpp │ ├── knuth optimization.cpp │ ├── li-chao.cpp │ └── sos DP.cpp ├── Game Theory │ └── grundy.cpp ├── Geometry │ ├── circle.cpp │ ├── closestPair.cpp │ ├── convex hull O(nlogn).cpp │ ├── geoTemplate.cpp │ ├── geoTemplate_old.cpp │ └── min_covering_circle.cpp ├── Graph │ ├── 2sat.cpp │ ├── articulation_points.cpp │ ├── bridges.cpp │ ├── centroid decomposition.cpp │ ├── centroid tree.cpp │ ├── diameterUnweighed.cpp │ ├── dinic-maxflow.cpp │ ├── dsu_for_bipartiteness.cpp │ ├── edmonds karp(ford fulkerson).cpp │ ├── euler_path_and_cycle.cpp │ ├── heavy_light_decomposition.cpp │ ├── lca.cpp │ ├── maximum bipartitie matching.cpp │ ├── min cost flow dijkstra.cpp │ ├── min cost flow.cpp │ ├── push-relable.cpp │ └── topological_sort_and_cycle_detection.cpp ├── Number Theory │ ├── crt restore.cpp │ ├── crt.cpp │ ├── discrete log ashishgup.cpp │ ├── discrete log.cpp │ ├── factorials.cpp │ ├── fast_factorization.cpp │ ├── generator.cpp │ ├── miller_rabin.cpp │ ├── mobius.cpp │ ├── modint.cpp │ ├── modinv.cpp │ ├── modinvex.cpp │ ├── primes │ ├── seive O(n).cpp │ ├── solovay_strasson_primality_check.cpp │ └── totient seive.cpp ├── Optimization │ └── simulatedAnnealing.cpp ├── Strings │ ├── kmp.cpp │ ├── manachers.cpp │ ├── rolling hash.cpp │ ├── suffix_array.cpp │ └── z function.cpp ├── comparator struct.cpp ├── random.cpp ├── stack_size.txt ├── template.cpp ├── ternary_search.cpp ├── time.cpp └── trace.cpp ├── python ├── stack+recursion.py └── template.py └── rust ├── data_structures ├── dsu.rs ├── queue.rs ├── segment_tree.rs ├── segment_tree_lazy_propagation.rs └── trie.rs ├── graphs ├── dfs.rs └── lca-binary-lifting.rs ├── number_theory ├── mod_inverse.rs └── sieve.rs ├── strings └── longest-palindromic-substring-manacher.rs ├── template.rs └── utils └── merge_sorted_vectors.rs /Config/makefile: -------------------------------------------------------------------------------- 1 | # All credit to ecnerwala 2 | # +--------------------+ 3 | # | | 4 | # | GENERAL CONFIG | 5 | # | | 6 | # +--------------------+ 7 | 8 | PROBLEM_NAME := problem_name 9 | DEBUG := true 10 | LANG := cpp 11 | 12 | ifeq ($(LANG),cpp) 13 | TARGET := $(PROBLEM_NAME) 14 | EXECUTE := ./$(TARGET) 15 | CLEAN_TARGETS := $(TARGET) 16 | else ifeq ($(LANG),python) 17 | TARGET := $(PROBLEM_NAME).py 18 | EXECUTE := python3 ./$(TARGET) 19 | CLEAN_TARGETS := 20 | else 21 | $(error "Unknown language; please set TARGET, EXECUTE, and CLEAN_TARGETS manually") 22 | endif 23 | 24 | CXX := g++ 25 | CXXFLAGS := -std=c++17 -O2 -D LOCAL -Wall -Wextra -pedantic -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -Wno-unused-result -Wno-sign-conversion 26 | DEBUG_CXXFLAGS := -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize-recover=all -fstack-protector-all -D_FORTIFY_SOURCE=2 27 | DEBUG_CXXFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC 28 | 29 | PRECOMPILE_HEADERS := bits/stdc++.h 30 | #PRECOMPILE_HEADERS := bits/extc++.h 31 | 32 | 33 | # +-------------------+ 34 | # | | 35 | # | GENERAL RULES | 36 | # | | 37 | # +-------------------+ 38 | 39 | all: $(TARGET) 40 | .PHONY: all 41 | 42 | clean: 43 | -rm -rf $(CLEAN_TARGETS) 44 | .PHONY: clean 45 | 46 | veryclean: 47 | -rm -rf $(CLEAN_TARGETS) *.res 48 | .PHONY: veryclean 49 | 50 | rebuild: clean all 51 | .PHONY: rebuild 52 | 53 | # +---------------------+ 54 | # | | 55 | # | C++ COMPILATION | 56 | # | | 57 | # +---------------------+ 58 | 59 | ifeq ($(DEBUG),true) 60 | CXXFLAGS += $(DEBUG_CXXFLAGS) 61 | endif 62 | 63 | PCH := .precompiled_headers 64 | # CLEAN_TARGETS += $(PCH) 65 | 66 | $(PCH)/%.gch: 67 | rm -f $@ 68 | mkdir -p $(dir $@) 69 | $(LINK.cpp) -x c++-header "$$(echo '#include<$*>' | $(LINK.cpp) -H -E -x c++ - 2>&1 >/dev/null | head -1 | cut -d ' ' -f2)" -o $@ 70 | .PRECIOUS: $(PCH)/%.gch 71 | 72 | %: %.cpp # Cancel the builtin rule 73 | 74 | %: %.cpp $(patsubst %,$(PCH)/%.gch,$(PRECOMPILE_HEADERS)) 75 | $(LINK.cpp) -isystem $(PCH) $< $(LOADLIBES) $(LDLIBS) -o $@ 76 | .PRECIOUS: % 77 | 78 | 79 | # +-----------------------+ 80 | # | | 81 | # | RUNNING / TESTING | 82 | # | | 83 | # +-----------------------+ 84 | 85 | export TIME=\n real\t%es\n user\t%Us\n sys\t%Ss\n mem\t%MKB 86 | 87 | run: $(TARGET) 88 | \time $(EXECUTE) 89 | ifeq ($(DEBUG),true) 90 | @echo "Built with DEBUG flags enabled, code may be slower than normal" 91 | endif 92 | .PHONY: run 93 | 94 | %.res: $(TARGET) %.in 95 | \time $(EXECUTE) < $*.in > $*.res 96 | ifeq ($(DEBUG),true) 97 | @echo "Built with DEBUG flags enabled, code may be slower than normal" 98 | endif 99 | .PRECIOUS: %.res 100 | 101 | %.out: % # Cancel the builtin rule 102 | 103 | __test_%: %.res %.out 104 | diff $*.res $*.out 105 | .PHONY: __test_% 106 | 107 | CASES := $(sort $(basename $(wildcard *.in))) 108 | TESTS := $(sort $(basename $(wildcard *.out))) 109 | 110 | runs: $(patsubst %,%.res,$(CASES)) 111 | .PHONY: run 112 | 113 | solve: runs 114 | .PHONY: solve 115 | 116 | test: $(patsubst %,__test_%,$(TESTS)) 117 | .PHONY: test -------------------------------------------------------------------------------- /Config/sublime/c++ konsole.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "shell_cmd": "g++ -std=c++11 -D LOCAL -Wall \"${file}\" -o \"${file_path}/${file_base_name}\" && konsole --hold -e \"${file_path}/./${file_base_name}\"", 3 | "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", 4 | "shell": true, 5 | "working_dir": "${file_path}", 6 | "selector": "source.c++, source.cxx, source.cpp, source.cc", 7 | 8 | "variants": 9 | [ 10 | { 11 | "name": "Run", 12 | "shell_cmd": "konsole --hold -e ${file_path}/./${file_base_name}" 13 | }, 14 | { 15 | "name": "Sanitize", 16 | "shell_cmd": "g++ -std=c++11 -D LOCAL -Wall \"${file}\" -o \"${file_path}/${file_base_name}\" -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG -g && konsole --hold -e \"${file_path}/./${file_base_name}\"" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /Config/sublime/cmd.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "shell_cmd": "make" 3 | } 4 | -------------------------------------------------------------------------------- /Config/vs code/makefile: -------------------------------------------------------------------------------- 1 | # All credit to ecnerwala 2 | # +--------------------+ 3 | # | | 4 | # | GENERAL CONFIG | 5 | # | | 6 | # +--------------------+ 7 | 8 | PROBLEM_NAME := problem_name 9 | DEBUG := true 10 | LANG := cpp 11 | 12 | ifeq ($(LANG),cpp) 13 | TARGET := $(PROBLEM_NAME) 14 | EXECUTE := ./$(TARGET) 15 | CLEAN_TARGETS := $(TARGET) 16 | else ifeq ($(LANG),python) 17 | TARGET := $(PROBLEM_NAME).py 18 | EXECUTE := python3 ./$(TARGET) 19 | CLEAN_TARGETS := 20 | else 21 | $(error "Unknown language; please set TARGET, EXECUTE, and CLEAN_TARGETS manually") 22 | endif 23 | 24 | CXX := g++ 25 | CXXFLAGS := -std=c++17 -O2 -D LOCAL -Wall -Wextra -pedantic -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -Wno-unused-result -Wno-sign-conversion 26 | DEBUG_CXXFLAGS := -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize-recover=all -fstack-protector-all -D_FORTIFY_SOURCE=2 27 | DEBUG_CXXFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC 28 | 29 | PRECOMPILE_HEADERS := bits/stdc++.h 30 | #PRECOMPILE_HEADERS := bits/extc++.h 31 | 32 | 33 | # +-------------------+ 34 | # | | 35 | # | GENERAL RULES | 36 | # | | 37 | # +-------------------+ 38 | 39 | all: $(TARGET) 40 | .PHONY: all 41 | 42 | clean: 43 | -rm -rf $(CLEAN_TARGETS) 44 | .PHONY: clean 45 | 46 | veryclean: 47 | -rm -rf $(CLEAN_TARGETS) *.res 48 | .PHONY: veryclean 49 | 50 | rebuild: clean all 51 | .PHONY: rebuild 52 | 53 | # +---------------------+ 54 | # | | 55 | # | C++ COMPILATION | 56 | # | | 57 | # +---------------------+ 58 | 59 | ifeq ($(DEBUG),true) 60 | CXXFLAGS += $(DEBUG_CXXFLAGS) 61 | endif 62 | 63 | PCH := .precompiled_headers 64 | # CLEAN_TARGETS += $(PCH) 65 | 66 | $(PCH)/%.gch: 67 | rm -f $@ 68 | mkdir -p $(dir $@) 69 | $(LINK.cpp) -x c++-header "$$(echo '#include<$*>' | $(LINK.cpp) -H -E -x c++ - 2>&1 >/dev/null | head -1 | cut -d ' ' -f2)" -o $@ 70 | .PRECIOUS: $(PCH)/%.gch 71 | 72 | %: %.cpp # Cancel the builtin rule 73 | 74 | %: %.cpp $(patsubst %,$(PCH)/%.gch,$(PRECOMPILE_HEADERS)) 75 | $(LINK.cpp) -isystem $(PCH) $< $(LOADLIBES) $(LDLIBS) -o $@ 76 | .PRECIOUS: % 77 | 78 | 79 | # +-----------------------+ 80 | # | | 81 | # | RUNNING / TESTING | 82 | # | | 83 | # +-----------------------+ 84 | 85 | export TIME=\n real\t%es\n user\t%Us\n sys\t%Ss\n mem\t%MKB 86 | 87 | run: $(TARGET) 88 | \time $(EXECUTE) 89 | ifeq ($(DEBUG),true) 90 | @echo "Built with DEBUG flags enabled, code may be slower than normal" 91 | endif 92 | .PHONY: run 93 | 94 | %.res: $(TARGET) %.in 95 | \time $(EXECUTE) < $*.in > $*.res 96 | ifeq ($(DEBUG),true) 97 | @echo "Built with DEBUG flags enabled, code may be slower than normal" 98 | endif 99 | .PRECIOUS: %.res 100 | 101 | %.out: % # Cancel the builtin rule 102 | 103 | __test_%: %.res %.out 104 | diff $*.res $*.out 105 | .PHONY: __test_% 106 | 107 | CASES := $(sort $(basename $(wildcard *.in))) 108 | TESTS := $(sort $(basename $(wildcard *.out))) 109 | 110 | runs: $(patsubst %,%.res,$(CASES)) 111 | .PHONY: run 112 | 113 | solve: runs 114 | .PHONY: solve 115 | 116 | test: $(patsubst %,__test_%,$(TESTS)) 117 | .PHONY: test -------------------------------------------------------------------------------- /Config/vs code/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "shell", 8 | "label": "build and run", 9 | "command": "ulimit -s unlimited && make run PROBLEM_NAME=${fileBasenameNoExtension} DEBUG=false", 10 | "group": { 11 | "kind": "build", 12 | "isDefault": true 13 | }, 14 | "options": { 15 | "cwd": "${workspaceFolder}/kitchen" 16 | 17 | }, 18 | }, 19 | { 20 | "type": "shell", 21 | "label": "debug", 22 | "command": "make clean run PROBLEM_NAME=${fileBasenameNoExtension} DEBUG=true", 23 | "options": { 24 | "cwd": "${workspaceFolder}/kitchen" 25 | }, 26 | "group": { 27 | "kind": "test", 28 | "isDefault": true 29 | } 30 | }, 31 | ] 32 | } -------------------------------------------------------------------------------- /cpp/Algebra/Z2 Vector Space.cpp: -------------------------------------------------------------------------------- 1 | // Refference : https://codeforces.com/blog/entry/68953 2 | struct vectorSpace{ 3 | typedef int base; 4 | int D, sz=0; 5 | vector basis; // basis[i] keeps the mask of the vector whose f value is i 6 | vectorSpace(int _D) 7 | { 8 | D=_D; 9 | basis.resize(D, 0); 10 | } 11 | void insert(base mask) 12 | { 13 | if(sz==D) return ; 14 | for(int i=D-1; i>=0; --i){ 15 | if(!((mask>>i)&1)) continue; 16 | if(!basis[i]){ 17 | basis[i]=mask; 18 | ++sz; 19 | return ; 20 | } 21 | mask^=basis[i]; 22 | } 23 | } 24 | bool represent(base mask) 25 | { 26 | if(sz==D) return 1; 27 | for(int i=D-1; i>=0; --i){ 28 | if(!((mask>>i)&1)) continue; 29 | if(!basis[i]) return 0; 30 | mask^=basis[i]; 31 | } 32 | return 1; 33 | } 34 | }; -------------------------------------------------------------------------------- /cpp/Algebra/fast_walsh_hadamard_transform.cpp: -------------------------------------------------------------------------------- 1 | #define poly vector 2 | 3 | void FWHT(poly &P, bool inverse) { 4 | int n=P.size(); 5 | for (int len = 1; 2 * len <= n; len <<= 1) { 6 | for (int i = 0; i < n; i += 2 * len) { 7 | for (int j = 0; j < len; j++) { 8 | ll u = P[i + j]; 9 | ll v = P[i + len + j]; 10 | if (!inverse) { 11 | P[i + j] = u + v; 12 | P[i + len + j] = u - v; 13 | } else { 14 | P[i + j] = u + v; 15 | P[i + len + j] = u - v; 16 | } 17 | } 18 | } 19 | } 20 | 21 | // required only for xor 22 | if (inverse) { 23 | for (int i = 0; i < n; i++){ 24 | assert(P[i]%n==0); 25 | P[i] = P[i]/n; 26 | } 27 | } 28 | } 29 | 30 | // n should be a power of 2 31 | poly multiply(poly p1, poly p2) 32 | { 33 | int n=p1.size(); 34 | FWHT(p1, 0), FWHT(p2, 0); 35 | poly res(n); 36 | for(int i=0; i 3 | T extGcd(T a, T b, T& x, T& y) { 4 | if (b == 0) { 5 | x = 1; 6 | y = 0; 7 | return a; 8 | } 9 | else { 10 | int g = extGcd(b, a % b, y, x); 11 | y -= a / b * x; 12 | return g; 13 | } 14 | } 15 | 16 | template 17 | T modInv(T a, T m) { 18 | T x, y; 19 | extGcd(a, m, x, y); 20 | return (x % m + m) % m; 21 | } 22 | 23 | long long crt(const std::vector< std::pair >& pp, int mod = -1); 24 | 25 | struct FFT_mod { 26 | int mod, root, root_1, root_pw; 27 | }; 28 | 29 | extern FFT_mod suggested_fft_mods[5]; 30 | void ntt_shortmod(std::vector& a, bool invert, const FFT_mod& mod_data); 31 | 32 | 33 | const int mod = 1000000007; 34 | const int MAGIC = 1024; 35 | 36 | vector mull(const vector& left, const vector& right, const FFT_mod& mod_data) { 37 | vector left1 = left, right1 = right; 38 | ntt_shortmod(left1, false, mod_data); 39 | ntt_shortmod(right1, false, mod_data); 40 | 41 | for (int i = 0; i < left.size(); i++) { 42 | left1[i] = (left1[i] * 1ll * right1[i]) % mod_data.mod; 43 | } 44 | 45 | ntt_shortmod(left1, true, mod_data); 46 | return left1; 47 | } 48 | 49 | vector brute(const vector& left, const vector& right) { 50 | int ssss = left.size() + right.size() - 1; 51 | vector ret(ssss, 0); 52 | 53 | for (int i = 0; i < left.size(); i++) { 54 | for (int j = 0; j < right.size(); j++) { 55 | ret[i+j] = (ret[i+j] + left[i]*1ll*right[j]) % mod; 56 | } 57 | } 58 | 59 | return ret; 60 | } 61 | 62 | vector mult(vector& left, vector& right) { 63 | int ssss = left.size() + right.size() - 1; 64 | if (ssss <= MAGIC) { 65 | return brute(left, right); 66 | } 67 | 68 | int pot2; 69 | for (pot2 = 1; pot2 < ssss; pot2 <<= 1); 70 | 71 | left.resize(pot2); 72 | right.resize(pot2); 73 | 74 | vector res[3]; 75 | for (int i = 0; i < 3; i++) { 76 | res[i] = mull(left, right, suggested_fft_mods[i]); 77 | } 78 | 79 | vector ret(pot2); 80 | for (int i = 0; i < pot2; i++) { 81 | vector< pair > mod_results; 82 | for (int j = 0; j < 3; j++) { 83 | mod_results.emplace_back(res[j][i], suggested_fft_mods[j].mod); 84 | } 85 | ret[i] = crt(mod_results, mod); 86 | } 87 | return ret; 88 | } 89 | 90 | vector rec(int st, int ed) { 91 | if (st == ed) { 92 | return vector{st, 1}; 93 | } 94 | 95 | int md = (st+ed)/2; 96 | vector left = rec(st, md); 97 | vector right = rec(md+1, ed); 98 | 99 | 100 | vector ret = mult(left, right); 101 | ret.resize(ed-st+2); 102 | return ret; 103 | } 104 | 105 | 106 | long long crt(const std::vector< std::pair >& a, int mod) { 107 | long long res = 0; 108 | long long mult = 1; 109 | 110 | int SZ = a.size(); 111 | std::vector x(SZ); 112 | for (int i = 0; i& a, bool invert, const FFT_mod& mod_data) { 144 | // only use if mod < 5*10^8 145 | int n = (int)a.size(); 146 | int mod = mod_data.mod; 147 | 148 | for (int i = 1, j = 0; i> 1; 150 | for (; j >= bit; bit >>= 1) 151 | j -= bit; 152 | j += bit; 153 | if (i < j) 154 | std::swap(a[i], a[j]); 155 | } 156 | 157 | for (int len = 2; len <= n; len <<= 1) { 158 | int wlen = invert ? mod_data.root_1 : mod_data.root; 159 | for (int i = len; i> 31; 166 | tt = (wlen * 1ll * tt - q * 1ll * mod) & ((1LL << 31) - 1); 167 | if (tt >= mod) tt -= mod; 168 | } 169 | for (int i = 0; i= 2*mod) uu -= 2*mod; 172 | a[i] = uu + vv; 173 | a[i + len / 2] = uu - vv + 2 * mod; 174 | 175 | for (int j = 1; j= 2*mod) u -= 2*mod; 178 | int q = (FFT_w_dash[j] * 1ll * a[i + j + len / 2]) >> 31; 179 | int v = (FFT_w[j] * 1ll * a[i + j + len / 2] - q * 1ll * mod) & ((1LL << 31) - 1); 180 | a[i + j] = u + v; 181 | a[i + j + len / 2] = u - v + 2*mod; 182 | } 183 | } 184 | } 185 | if (invert) { 186 | int nrev = modInv(n, mod); 187 | for (int i = 0; i point; 8 | 9 | point w[maxn]; 10 | const ftype pi = acos(-1); 11 | bool initiated = 0; 12 | void init() { 13 | if(!initiated) { 14 | for(int i = 1; i < maxn; i *= 2) { 15 | for(int j = 0; j < i; j++) { 16 | w[i + j] = polar(ftype(1), pi * j / i); 17 | } 18 | } 19 | initiated = 1; 20 | } 21 | } 22 | template 23 | void fft(T *in, point *out, int n, int k = 1) { 24 | if(n == 1) { 25 | *out = *in; 26 | } else { 27 | n /= 2; 28 | fft(in, out, n, 2 * k); 29 | fft(in + k, out + n, n, 2 * k); 30 | for(int i = 0; i < n; i++) { 31 | auto t = out[i + n] * w[i + n]; 32 | out[i + n] = out[i] - t; 33 | out[i] += t; 34 | } 35 | } 36 | } 37 | 38 | template 39 | void mul_slow(vector &a, const vector &b) { 40 | vector res(a.size() + b.size() - 1); 41 | for(size_t i = 0; i < a.size(); i++) { 42 | for(size_t j = 0; j < b.size(); j++) { 43 | res[i + j] += a[i] * b[j]; 44 | } 45 | } 46 | a = res; 47 | } 48 | 49 | 50 | template 51 | void mul(vector &a, const vector &b) { 52 | init(); 53 | if(min(a.size(), b.size()) < magic) { 54 | mul_slow(a, b); 55 | return; 56 | } 57 | 58 | static const int shift = 15, mask = (1 << shift) - 1; 59 | size_t n = a.size() + b.size() - 1; 60 | while(__builtin_popcount(n) != 1) { 61 | n++; 62 | } 63 | a.resize(n); 64 | static point A[maxn], B[maxn]; 65 | static point C[maxn], D[maxn]; 66 | for(size_t i = 0; i < n; i++) { 67 | A[i] = point(a[i] & mask, a[i] >> shift); 68 | if(i < b.size()) { 69 | B[i] = point(b[i] & mask, b[i] >> shift); 70 | } else { 71 | B[i] = 0; 72 | } 73 | } 74 | fft(A, C, n); fft(B, D, n); 75 | for(size_t i = 0; i < n; i++) { 76 | point c0 = C[i] + conj(C[(n - i) % n]); 77 | point c1 = C[i] - conj(C[(n - i) % n]); 78 | point d0 = D[i] + conj(D[(n - i) % n]); 79 | point d1 = D[i] - conj(D[(n - i) % n]); 80 | A[i] = c0 * d0 - point(0, 1) * c1 * d1; 81 | B[i] = c0 * d1 + d0 * c1; 82 | } 83 | fft(A, C, n); fft(B, D, n); 84 | reverse(C + 1, C + n); 85 | reverse(D + 1, D + n); 86 | int t = 4 * n; 87 | for(size_t i = 0; i < n; i++) { 88 | int64_t A0 = llround(real(C[i]) / t); 89 | T A1 = llround(imag(D[i]) / t); 90 | T A2 = llround(imag(C[i]) / t); 91 | a[i] = A0 + (A1 << shift) + (A2 << 2 * shift); 92 | } 93 | return; 94 | } 95 | } -------------------------------------------------------------------------------- /cpp/Algebra/fft_jtnydv.cpp: -------------------------------------------------------------------------------- 1 | //attribution: Jatin Yadav on codechef 2 | namespace fft{ 3 | #define ld double 4 | #define poly vector 5 | 6 | struct base{ 7 | ld x,y; 8 | base(){x=y=0;} 9 | base(ld _x, ld _y){x = _x,y = _y;} 10 | base(ld _x){x = _x, y = 0;} 11 | void operator = (ld _x){x = _x,y = 0;} 12 | ld real(){return x;} 13 | ld imag(){return y;} 14 | base operator + (const base& b){return base(x+b.x,y+b.y);} 15 | void operator += (const base& b){x+=b.x,y+=b.y;} 16 | base operator * (const base& b){return base(x*b.x - y*b.y,x*b.y+y*b.x);} 17 | void operator *= (const base& b){ld p = x*b.x - y*b.y, q = x*b.y+y*b.x; x = p, y = q;} 18 | void operator /= (ld k){x/=k,y/=k;} 19 | base operator - (const base& b){return base(x - b.x,y - b.y);} 20 | void operator -= (const base& b){x -= b.x, y -= b.y;} 21 | base conj(){ return base(x, -y);} 22 | base operator / (ld k) { return base(x / k, y / k);} 23 | void Print(){ cerr << x << " + " << y << "i\n";} 24 | }; 25 | double PI = 2.0*acos(0.0); 26 | const int MAXN = 19; 27 | const int maxn = 1< & a, bool invert) { 39 | if(fst) precompute_powers(), fst = 0; 40 | int n = (int) a.size(); 41 | 42 | for (int i=1, j=0; i> 1; 44 | for (; j>=bit; bit>>=1) 45 | j -= bit; 46 | j += bit; 47 | if (i < j) 48 | swap (a[i], a[j]); 49 | } 50 | for (int len=2; len<=n; len<<=1) { 51 | for (int i=0; i P(n), Q(n); 71 | int SQRTMOD = (int)sqrt(mod) + 10; 72 | for(int i = 0;i < n1;i++) P[i] = base(a[i] % SQRTMOD, a[i] / SQRTMOD); 73 | for(int i = 0;i < n2;i++) Q[i] = base(b[i] % SQRTMOD, b[i] / SQRTMOD); 74 | fft(P, 0); 75 | fft(Q, 0); 76 | base A1, A2, B1, B2, X, Y; 77 | for(int i = 0; i < n; i++){ 78 | X = P[i]; 79 | Y = P[(n - i) % n].conj(); 80 | A1 = (X + Y) * base(0.5, 0); 81 | A2 = (X - Y) * base(0, -0.5); 82 | X = Q[i]; 83 | Y = Q[(n - i) % n].conj(); 84 | B1 = (X + Y) * base(0.5, 0); 85 | B2 = (X - Y) * base(0, -0.5); 86 | P1[i] = A1 * B1 + A2 * B2 * base(0, 1); 87 | Q1[i] = A1 * B2 + A2 * B1; 88 | } 89 | for(int i = 0; i < n; i++) P[i] = P1[i], Q[i] = Q1[i]; 90 | fft(P, 1); 91 | fft(Q, 1); 92 | poly ret(final_size); 93 | for(int i = 0; i < final_size; i++){ 94 | ll x = (ll)(P[i].real() + 0.5); 95 | ll y = (ll)(P[i].imag() + 0.5) % mod; 96 | ll z = (ll)(Q[i].real() + 0.5); 97 | ret[i] = (x + ((y * SQRTMOD + z) % mod) * SQRTMOD) % mod; 98 | } 99 | return ret; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /cpp/Algebra/linear equations gauss elimination.cpp: -------------------------------------------------------------------------------- 1 | // Attrribution: Neal Wu on Codeforces 2 | // Warning: this only handles the case where # equations >= # variables and there is a valid solution. 3 | template 4 | struct gaussian { 5 | int n; 6 | vector> coefficients; 7 | vector values; 8 | 9 | gaussian(int _n = 0) { 10 | init(_n); 11 | } 12 | 13 | void init(int _n) { 14 | n = _n; 15 | coefficients = {}; 16 | values = {}; 17 | } 18 | 19 | void add_equation(const vector &coefs, float_t value) { 20 | assert(int(coefs.size()) == n); 21 | coefficients.push_back(coefs); 22 | values.push_back(value); 23 | } 24 | 25 | void swap_rows(int a, int b) { 26 | swap(coefficients[a], coefficients[b]); 27 | swap(values[a], values[b]); 28 | } 29 | 30 | // Eliminates `coefficients[target][col]` by canceling the `target` row with the `source` row. 31 | void eliminate(int target, int source, int col, int start_col = 0) { 32 | if (coefficients[target][col] == 0) 33 | return; 34 | 35 | assert(coefficients[source][col] != 0); 36 | float_t ratio = coefficients[target][col] / coefficients[source][col]; 37 | 38 | for (int i = start_col; i < n; i++) 39 | coefficients[target][i] -= coefficients[source][i] * ratio; 40 | 41 | coefficients[target][col] = 0; 42 | values[target] -= values[source] * ratio; 43 | } 44 | 45 | vector solve() { 46 | int rows = int(coefficients.size()); 47 | assert(rows >= n); 48 | 49 | for (int i = 0; i < n; i++) { 50 | int largest = i; 51 | 52 | for (int row = i + 1; row < rows; row++) 53 | if (coefficients[row][i] > coefficients[largest][i]) 54 | largest = row; 55 | 56 | swap_rows(largest, i); 57 | 58 | for (int row = i + 1; row < rows; row++) 59 | eliminate(row, i, i, i); 60 | } 61 | 62 | vector answers(n, 0); 63 | 64 | for (int i = n - 1; i >= 0; i--) { 65 | for (int j = 0; j < i; j++) 66 | assert(coefficients[i][j] == 0); 67 | 68 | float_t value = values[i]; 69 | 70 | for (int j = i + 1; j < n; j++) 71 | value -= coefficients[i][j] * answers[j]; 72 | 73 | answers[i] = value / coefficients[i][i]; 74 | } 75 | 76 | return answers; 77 | } 78 | }; -------------------------------------------------------------------------------- /cpp/Algebra/linear recurrance O(mlog^2n).cpp: -------------------------------------------------------------------------------- 1 | //refference: https://discuss.codechef.com/questions/65993/rng-editorial 2 | 3 | const int mod = 1e9+7; 4 | 5 | inline void add(int &a, int b) { 6 | a += b; 7 | if (a >= mod) a -= mod; 8 | } 9 | inline void sub(int &a, int b) { 10 | a -= b; 11 | if (a < 0) a += mod; 12 | } 13 | 14 | inline int mul(int a, int b) { 15 | #if !defined(_WIN32) || defined(_WIN64) 16 | return (int) ((long long) a * b % mod); 17 | #endif 18 | unsigned long long x = (long long) a * b; 19 | unsigned xh = (unsigned) (x >> 32), xl = (unsigned) x, d, m; 20 | asm( 21 | "divl %4; \n\t" 22 | : "=a" (d), "=d" (m) 23 | : "d" (xh), "a" (xl), "r" (mod) 24 | ); 25 | return m; 26 | } 27 | 28 | 29 | inline int power(int a, long long b) { 30 | int res = 1; 31 | while (b > 0) { 32 | if (b & 1) { 33 | res = mul(res, a); 34 | } 35 | a = mul(a, a); 36 | b >>= 1; 37 | } 38 | return res; 39 | } 40 | inline int inv(int a) { 41 | a %= mod; 42 | if (a < 0) a += mod; 43 | int b = mod, u = 0, v = 1; 44 | while (a) { 45 | int t = b / a; 46 | b -= t * a; swap(a, b); 47 | u -= t * v; swap(u, v); 48 | } 49 | assert(b == 1); 50 | if (u < 0) u += mod; 51 | return u; 52 | } 53 | 54 | //attribution: Jatin Yadav on codechef 55 | namespace fft{ 56 | #define ld double 57 | #define poly vector 58 | 59 | struct base{ 60 | ld x,y; 61 | base(){x=y=0;} 62 | base(ld _x, ld _y){x = _x,y = _y;} 63 | base(ld _x){x = _x, y = 0;} 64 | void operator = (ld _x){x = _x,y = 0;} 65 | ld real(){return x;} 66 | ld imag(){return y;} 67 | base operator + (const base& b){return base(x+b.x,y+b.y);} 68 | void operator += (const base& b){x+=b.x,y+=b.y;} 69 | base operator * (const base& b){return base(x*b.x - y*b.y,x*b.y+y*b.x);} 70 | void operator *= (const base& b){ld p = x*b.x - y*b.y, q = x*b.y+y*b.x; x = p, y = q;} 71 | void operator /= (ld k){x/=k,y/=k;} 72 | base operator - (const base& b){return base(x - b.x,y - b.y);} 73 | void operator -= (const base& b){x -= b.x, y -= b.y;} 74 | base conj(){ return base(x, -y);} 75 | base operator / (ld k) { return base(x / k, y / k);} 76 | void Print(){ cerr << x << " + " << y << "i\n";} 77 | }; 78 | double PI = 2.0*acos(0.0); 79 | const int MAXN = 17; 80 | const int maxn = 1< & a, bool invert) { 92 | if(fst) precompute_powers(), fst = 0; 93 | int n = (int) a.size(); 94 | 95 | for (int i=1, j=0; i> 1; 97 | for (; j>=bit; bit>>=1) 98 | j -= bit; 99 | j += bit; 100 | if (i < j) 101 | swap (a[i], a[j]); 102 | } 103 | for (int len=2; len<=n; len<<=1) { 104 | for (int i=0; i P(n), Q(n); 124 | int SQRTMOD = (int)sqrt(mod) + 10; 125 | for(int i = 0;i < n1;i++) P[i] = base(a[i] % SQRTMOD, a[i] / SQRTMOD); 126 | for(int i = 0;i < n2;i++) Q[i] = base(b[i] % SQRTMOD, b[i] / SQRTMOD); 127 | fft(P, 0); 128 | fft(Q, 0); 129 | base A1, A2, B1, B2, X, Y; 130 | for(int i = 0; i < n; i++){ 131 | X = P[i]; 132 | Y = P[(n - i) % n].conj(); 133 | A1 = (X + Y) * base(0.5, 0); 134 | A2 = (X - Y) * base(0, -0.5); 135 | X = Q[i]; 136 | Y = Q[(n - i) % n].conj(); 137 | B1 = (X + Y) * base(0.5, 0); 138 | B2 = (X - Y) * base(0, -0.5); 139 | P1[i] = A1 * B1 + A2 * B2 * base(0, 1); 140 | Q1[i] = A1 * B2 + A2 * B1; 141 | } 142 | for(int i = 0; i < n; i++) P[i] = P1[i], Q[i] = Q1[i]; 143 | fft(P, 1); 144 | fft(Q, 1); 145 | poly ret(final_size); 146 | for(int i = 0; i < final_size; i++){ 147 | ll x = (ll)(P[i].real() + 0.5); 148 | ll y = (ll)(P[i].imag() + 0.5) % mod; 149 | ll z = (ll)(Q[i].real() + 0.5); 150 | ret[i] = (x + ((y * SQRTMOD + z) % mod) * SQRTMOD) % mod; 151 | } 152 | return ret; 153 | } 154 | } 155 | 156 | 157 | //use your favourate fast polynomial multiplication algo here 158 | vll mult(vll a,vll b, int upper_limit = 1e9) { 159 | vll c; 160 | int sz1 = a.size(); 161 | int sz2 = b.size(); 162 | if(min(sz1, sz2)<=5){ 163 | c.resize(sz1 + sz2 - 1); 164 | for (int i = 0;i < sz1;++i) 165 | for (int j = 0;j < sz2;++j) 166 | c[i + j]=(c[i+j]+a[i]*b[j])%mod; 167 | } 168 | else c=fft::mult(a, b, mod); 169 | if((int)c.size() > upper_limit) c.resize(upper_limit); 170 | return c; 171 | } 172 | 173 | //attribution: https://www.codechef.com/viewsolution/19110694 174 | namespace poly_ops{ 175 | typedef ll base; 176 | inline int add(int x, int y){ x += y; if(x >= mod) x -= mod; return x;} 177 | inline int sub(int x, int y){ x -= y; if(x < 0) x += mod; return x;} 178 | 179 | vector truncate_end(vector v){ 180 | while(!v.empty() && v.back() == 0) v.pop_back(); 181 | if(v.empty()) v = {0}; 182 | return v; 183 | } 184 | 185 | vector add(vector a, vector b){ 186 | vector ret(max(a.size(), b.size())); 187 | for(int i = 0; i < (int)ret.size(); i++){ 188 | ret[i] = add(i < (int)a.size() ? a[i] : 0, i < (int)b.size() ? b[i] : 0); 189 | } 190 | return ret; 191 | } 192 | 193 | vector sub(vector a, vector b){ 194 | vector ret(max(a.size(), b.size())); 195 | for(int i = 0; i < (int)ret.size(); i++){ 196 | ret[i] = sub(i < (int)a.size() ? a[i] : 0, i < (int)b.size() ? b[i] : 0); 197 | } 198 | return ret; 199 | } 200 | 201 | vector mul_scalar(vector v, int k){ 202 | for(auto & it : v) it = mul(k, it); 203 | return v; 204 | } 205 | 206 | vector get_first(vector v, int k){ 207 | v.resize(min((int)v.size(), k)); 208 | return v; 209 | } 210 | 211 | vector inverse(vector a, int sz){ 212 | assert(a[0] != 0); 213 | vector x = {inv(a[0])}; 214 | while((int)x.size() < sz){ 215 | vector temp(a.begin(), a.begin() + min(a.size(), 2 * x.size())); 216 | vector nx = mult(mult(x, x), temp); 217 | x.resize(2 * x.size()); 218 | for(int i = 0; i < (int)x.size(); i++) 219 | x[i] = sub(add(x[i], x[i]), nx[i]); 220 | } 221 | x.resize(sz); 222 | return x; 223 | } 224 | 225 | vector differentiate(vector f){ 226 | for(int i = 0; i + 1 < (int)f.size(); i++) f[i] = mul(i + 1, f[i + 1]); 227 | if(!f.empty()) f.resize(f.size() - 1); 228 | if(f.empty()) f = {0}; 229 | return f; 230 | } 231 | 232 | vector integrate(vector f, int c = 0){ 233 | f.resize(f.size() + 1); 234 | for(int i = f.size(); i >= 1; i--) f[i] = mul(f[i - 1], inv(i)); 235 | f[0] = c; 236 | return f; 237 | } 238 | 239 | vector Log(vector f, int k){ 240 | assert(f[0] == 1); 241 | vector inv_f = inverse(f, k); 242 | return integrate(mult(differentiate(f), inv_f, k)) ; 243 | } 244 | 245 | vector Exp(vector f, int k){ 246 | assert(f[0] == 0); 247 | vector g = {1}; 248 | while((int)g.size() < k){ 249 | int curr_sz = g.size(); 250 | g = mult(g, get_first(add(f, sub({1}, Log(g, 2 * curr_sz))), 2 * curr_sz), 2 * curr_sz); 251 | } 252 | 253 | g.resize(k); 254 | return g; 255 | } 256 | 257 | vector powr(vector X, long long n, int k){ 258 | int common = X[0]; 259 | int inv_com = inv(common); 260 | X = mul_scalar(X, inv_com); 261 | n %= mod; 262 | vector ret = Exp(mul_scalar(Log(X, k + 1), n), k); 263 | ret.resize(k); 264 | ret = mul_scalar(ret, power(common, n)); 265 | return ret; 266 | } 267 | 268 | vector divmod(vector f, vector g){ 269 | if(f.size() < g.size()) return f; 270 | int sz = f.size() - g.size() + 1; 271 | reverse(f.begin(), f.end()); reverse(g.begin(), g.end()); 272 | vector inv2 = inverse(g, sz); 273 | vector _p = f; _p.resize(sz); 274 | vector q = mult(inv2, _p); 275 | q.resize(sz); 276 | reverse(q.begin(), q.end()); reverse(f.begin(), f.end()); reverse(g.begin(), g.end()); 277 | return truncate_end(sub(f, mult(g, q))); 278 | } 279 | } 280 | 281 | //recurrance defined by: f[n] = sigma(i from n->1) f[n-i]*rec[n-i] 282 | struct linearRecurrance{ 283 | vll M; //don't change these 284 | vll base; //value of f[0..n-1] 285 | vll rec; //value of coefficients of recursion 286 | int n; //size of recursion 287 | vll pre_powers[61]; //precalculate powers to save time 288 | 289 | linearRecurrance(vll _base, vll _rec):base(_base), rec(_rec), n(_rec.size()) 290 | { 291 | M.resize(n+1); 292 | M[n]=1; 293 | for(int i=0; i>i)&1) vec=poly_ops::divmod(mult(vec, pre_powers[i]), M); 318 | } 319 | ll ans=0; 320 | for(int i=0; i 2 | #define ll long long 3 | #define pii pair 4 | #define pli pair 5 | #define pil pair 6 | #define pll pair 7 | #define dub double 8 | #define pdd pair 9 | #define vi vector 10 | #define vl vector 11 | #define vc vector 12 | #define vll vector 13 | #define vb vector 14 | #define vd vector 15 | #define vs vector 16 | #define vpii vector 17 | #define vpil vector 18 | #define vpli vector 19 | #define vpll vector 20 | #define ff first 21 | #define ss second 22 | #define mp make_pair 23 | #define pb push_back 24 | #define ppb pop_back 25 | #define pf push_front 26 | #define ppf pop_front 27 | #define eb emplace_back 28 | #define lwr lower_bound 29 | #define upr upper_bound 30 | #define pq priority_queue 31 | #define umap unordered_map 32 | #define all(x) x.begin(),x.end() 33 | #define clr(a,b) memset(a,b,sizeof a) 34 | #define fr(i,n) for(int i=0; i; 12 | 13 | static void extand(vec &a, size_t d, int64 value = 0) { 14 | if (d <= a.size()) return; 15 | a.resize(d, value); 16 | } 17 | static vec BerlekampMassey(const vec &s, int64 mod) { 18 | std::function inverse = [&](int64 a) { 19 | return a == 1 ? 1 : (int64)(mod - mod / a) * inverse(mod % a) % mod; 20 | }; 21 | vec A = {1}, B = {1}; 22 | int64 b = s[0]; 23 | for (size_t i = 1, m = 1; i < s.size(); ++i, m++) { 24 | int64 d = 0; 25 | for (size_t j = 0; j < A.size(); ++j) { 26 | d += A[j] * s[i - j] % mod; 27 | } 28 | if (!(d %= mod)) continue; 29 | if (2 * (A.size() - 1) <= i) { 30 | auto temp = A; 31 | extand(A, B.size() + m); 32 | int64 coef = d * inverse(b) % mod; 33 | for (size_t j = 0; j < B.size(); ++j) { 34 | A[j + m] -= coef * B[j] % mod; 35 | if (A[j + m] < 0) A[j + m] += mod; 36 | } 37 | B = temp, b = d, m = 0; 38 | } else { 39 | extand(A, B.size() + m); 40 | int64 coef = d * inverse(b) % mod; 41 | for (size_t j = 0; j < B.size(); ++j) { 42 | A[j + m] -= coef * B[j] % mod; 43 | if (A[j + m] < 0) A[j + m] += mod; 44 | } 45 | } 46 | } 47 | return A; 48 | } 49 | static void exgcd(int64 a, int64 b, int64 &g, int64 &x, int64 &y) { 50 | if (!b) x = 1, y = 0, g = a; 51 | else { 52 | exgcd(b, a % b, g, y, x); 53 | y -= x * (a / b); 54 | } 55 | } 56 | static int64 crt(const vec &c, const vec &m) { 57 | int n = c.size(); 58 | int64 M = 1, ans = 0; 59 | for (int i = 0; i < n; ++i) M *= m[i]; 60 | for (int i = 0; i < n; ++i) { 61 | int64 x, y, g, tm = M / m[i]; 62 | exgcd(tm, m[i], g, x, y); 63 | ans = (ans + tm * x * c[i] % M) % M; 64 | } 65 | return (ans + M) % M; 66 | } 67 | static vec ReedsSloane(const vec &s, int64 mod) { 68 | auto inverse = [] (int64 a, int64 m) { 69 | int64 d, x, y; 70 | exgcd(a, m, d, x, y); 71 | return d == 1 ? (x % m + m) % m : -1; 72 | }; 73 | auto L = [] (const vec &a, const vec &b) { 74 | int da = (a.size() > 1 || (a.size() == 1 && a[0])) ? a.size() - 1 : -1000; 75 | int db = (b.size() > 1 || (b.size() == 1 && b[0])) ? b.size() - 1 : -1000; 76 | return std::max(da, db + 1); 77 | }; 78 | auto prime_power = [&] (const vec &s, int64 mod, int64 p, int64 e) { 79 | // linear feedback shift register mod p^e, p is prime 80 | std::vector a(e), b(e), an(e), bn(e), ao(e), bo(e); 81 | vec t(e), u(e), r(e), to(e, 1), uo(e), pw(e + 1);; 82 | pw[0] = 1; 83 | for (int i = pw[0] = 1; i <= e; ++i) pw[i] = pw[i - 1] * p; 84 | for (int64 i = 0; i < e; ++i) { 85 | a[i] = {pw[i]}, an[i] = {pw[i]}; 86 | b[i] = {0}, bn[i] = {s[0] * pw[i] % mod}; 87 | t[i] = s[0] * pw[i] % mod; 88 | if (t[i] == 0) { 89 | t[i] = 1, u[i] = e; 90 | } else { 91 | for (u[i] = 0; t[i] % p == 0; t[i] /= p, ++u[i]); 92 | } 93 | } 94 | for (size_t k = 1; k < s.size(); ++k) { 95 | for (int g = 0; g < e; ++g) { 96 | if (L(an[g], bn[g]) > L(a[g], b[g])) { 97 | ao[g] = a[e - 1 - u[g]]; 98 | bo[g] = b[e - 1 - u[g]]; 99 | to[g] = t[e - 1 - u[g]]; 100 | uo[g] = u[e - 1 - u[g]]; 101 | r[g] = k - 1; 102 | } 103 | } 104 | a = an, b = bn; 105 | for (int o = 0; o < e; ++o) { 106 | int64 d = 0; 107 | for (size_t i = 0; i < a[o].size() && i <= k; ++i) { 108 | d = (d + a[o][i] * s[k - i]) % mod; 109 | } 110 | if (d == 0) { 111 | t[o] = 1, u[o] = e; 112 | } else { 113 | for (u[o] = 0, t[o] = d; t[o] % p == 0; t[o] /= p, ++u[o]); 114 | int g = e - 1 - u[o]; 115 | if (L(a[g], b[g]) == 0) { 116 | extand(bn[o], k + 1); 117 | bn[o][k] = (bn[o][k] + d) % mod; 118 | } else { 119 | int64 coef = t[o] * inverse(to[g], mod) % mod * pw[u[o] - uo[g]] % mod; 120 | int m = k - r[g]; 121 | extand(an[o], ao[g].size() + m); 122 | extand(bn[o], bo[g].size() + m); 123 | for (size_t i = 0; i < ao[g].size(); ++i) { 124 | an[o][i + m] -= coef * ao[g][i] % mod; 125 | if (an[o][i + m] < 0) an[o][i + m] += mod; 126 | } 127 | while (an[o].size() && an[o].back() == 0) an[o].pop_back(); 128 | for (size_t i = 0; i < bo[g].size(); ++i) { 129 | bn[o][i + m] -= coef * bo[g][i] % mod; 130 | if (bn[o][i + m] < 0) bn[o][i + m] -= mod; 131 | } 132 | while (bn[o].size() && bn[o].back() == 0) bn[o].pop_back(); 133 | } 134 | } 135 | } 136 | } 137 | return std::make_pair(an[0], bn[0]); 138 | }; 139 | 140 | std::vector> fac; 141 | for (int64 i = 2; i * i <= mod; ++i) if (mod % i == 0) { 142 | int64 cnt = 0, pw = 1; 143 | while (mod % i == 0) mod /= i, ++cnt, pw *= i; 144 | fac.emplace_back(pw, i, cnt); 145 | } 146 | if (mod > 1) fac.emplace_back(mod, mod, 1); 147 | std::vector as; 148 | size_t n = 0; 149 | for (auto &&x: fac) { 150 | int64 mod, p, e; 151 | vec a, b; 152 | std::tie(mod, p, e) = x; 153 | auto ss = s; 154 | for (auto &&x: ss) x %= mod; 155 | std::tie(a, b) = prime_power(ss, mod, p, e); 156 | as.emplace_back(a); 157 | n = std::max(n, a.size()); 158 | } 159 | vec a(n), c(as.size()), m(as.size()); 160 | for (size_t i = 0; i < n; ++i) { 161 | for (size_t j = 0; j < as.size(); ++j) { 162 | m[j] = std::get<0>(fac[j]); 163 | c[j] = i < as[j].size() ? as[j][i] : 0; 164 | } 165 | a[i] = crt(c, m); 166 | } 167 | return a; 168 | } 169 | 170 | LinearRecurrence(const vec &s, const vec &c, int64 mod): 171 | init(s), trans(c), mod(mod), m(s.size()) {} 172 | LinearRecurrence(const vec &s, int64 mod, bool is_prime = true): mod(mod) { 173 | vec A; 174 | if (is_prime) A = BerlekampMassey(s, mod); 175 | else A = ReedsSloane(s, mod); 176 | if (A.empty()) A = {0}; 177 | m = A.size() - 1; 178 | trans.resize(m); 179 | for (int i = 0; i < m; ++i) { 180 | trans[i] = (mod - A[i + 1]) % mod; 181 | } 182 | std::reverse(trans.begin(), trans.end()); 183 | init = {s.begin(), s.begin() + m}; 184 | } 185 | int64 calc(int64 n) { 186 | if (mod == 1) return 0; 187 | if (n < m) return init[n]; 188 | vec v(m), u(m << 1); 189 | int msk = !!n; 190 | for (int64 m = n; m > 1; m >>= 1) msk <<= 1; 191 | v[0] = 1 % mod; 192 | for (int x = 0; msk; msk >>= 1, x <<= 1) { 193 | std::fill_n(u.begin(), m * 2, 0); 194 | x |= !!(n & msk); 195 | if (x < m) u[x] = 1 % mod; 196 | else {// can be optimized by fft/ntt 197 | for (int i = 0; i < m; ++i) { 198 | for (int j = 0, t = i + (x & 1); j < m; ++j, ++t) { 199 | u[t] = (u[t] + v[i] * v[j]) % mod; 200 | } 201 | } 202 | for (int i = m * 2 - 1; i >= m; --i) { 203 | for (int j = 0, t = i - m; j < m; ++j, ++t) { 204 | u[t] = (u[t] + trans[j] * u[i]) % mod; 205 | } 206 | } 207 | } 208 | v = {u.begin(), u.begin() + m}; 209 | } 210 | int64 ret = 0; 211 | for (int i = 0; i < m; ++i) { 212 | ret = (ret + v[i] * init[i]) % mod; 213 | } 214 | return ret; 215 | } 216 | 217 | vec init, trans; 218 | int64 mod; 219 | int m; 220 | }; -------------------------------------------------------------------------------- /cpp/Algebra/matrix functions.cpp: -------------------------------------------------------------------------------- 1 | //attribution: chemthan 2 | template 3 | struct Matrix { 4 | int x[n][n]; 5 | 6 | Matrix() { 7 | memset(x, 0, sizeof(x)); 8 | } 9 | int* operator [] (int r) { 10 | return x[r]; 11 | } 12 | static Matrix unit() { 13 | Matrix res; 14 | for (int i = 0; i < n; i++) res[i][i] = 1; 15 | return res; 16 | } 17 | friend Matrix operator + (Matrix A, Matrix B) { 18 | Matrix res; 19 | for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { 20 | res[i][j] = A[i][j] + B[i][j]; 21 | if (res[i][j] >= mod) res[i][j] -= mod; 22 | } 23 | return res; 24 | } 25 | friend Matrix operator * (Matrix A, Matrix B) { 26 | Matrix res; 27 | for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { 28 | long long SQmod = (long long) mod * mod; 29 | long long sum = 0; 30 | for (int k = 0; k < n; k++) { 31 | sum += (long long) A[i][k] * B[k][j]; 32 | if (sum >= SQmod) sum -= SQmod; 33 | } 34 | res[i][j] = sum % mod; 35 | } 36 | return res; 37 | } 38 | friend Matrix operator ^ (Matrix A, long long k) { 39 | if (k == 0) return unit(); 40 | Matrix res, tmp; 41 | for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { 42 | res[i][j] = tmp[i][j] = A[i][j]; 43 | } 44 | k--; 45 | while (k) { 46 | if (k & 1) res = res * tmp; 47 | tmp = tmp * tmp; 48 | k >>= 1; 49 | } 50 | return res; 51 | } 52 | //Calculate geometric series: A^0 + A^1 + ... + A^k 53 | friend Matrix geometricseries(Matrix A, long long k) { 54 | if (k == 0) return unit(); 55 | if (k == 1) return A + unit(); 56 | vector bit; 57 | while (k) { 58 | bit.push_back(k & 1); 59 | k >>= 1; 60 | } 61 | Matrix res = A, tmp = A; 62 | for (int i = bit.size() - 2; i >= 0; i--) { 63 | res = res + (res * tmp); 64 | tmp = tmp * tmp; 65 | if (bit[i] & 1) { 66 | tmp = tmp * A; 67 | res = res + tmp; 68 | } 69 | } 70 | res = res + unit(); 71 | return res; 72 | } 73 | }; -------------------------------------------------------------------------------- /cpp/Algebra/matrixMultiplication.cpp: -------------------------------------------------------------------------------- 1 | typedef vector> matrix; 2 | 3 | template 4 | void reshape(vector> &mat, int n, int m) 5 | { 6 | mat.assign(n, vector(m, T(0))); 7 | } 8 | 9 | template 10 | vector> operator*(vector> &mat1, vector> &mat2) 11 | { 12 | int n1=mat1.size(), m1=mat1[0].size(), n2=mat2.size(), m2=mat2[0].size(); 13 | assert(m1==n2); 14 | T sum; 15 | vector> ret; 16 | reshape(ret, n1, m2); 17 | 18 | for(int i=0; i 28 | vector> power(vector> res, ll ex) 29 | { 30 | auto tmp=res; 31 | --ex; 32 | while(ex>0){ 33 | if(ex&1) res=res*tmp; 34 | tmp=tmp*tmp; 35 | ex>>=1; 36 | } 37 | return res; 38 | } -------------------------------------------------------------------------------- /cpp/Algebra/ntt+crt.cpp: -------------------------------------------------------------------------------- 1 | //credit kevinsogo on hackerrank 2 | const ll mod = 100003; 3 | 4 | const ll mod0 = 1484783617; 5 | const ll root0 = 270076864; 6 | const ll iroot0 = 1400602088; 7 | 8 | const ll mod1 = 1572864001; 9 | const ll root1 = 682289494; 10 | const ll iroot1 = 1238769373; 11 | 12 | const ll root_pw = 1 << 22; 13 | 14 | #define Imod0mod1 898779447LL 15 | #define Imod1mod0 636335819LL 16 | 17 | #define chinese(a1,m1,a2,m2) ((a1 * I##m2##m1 % m1 * m2 + a2 * I##m1##m2 % m2 * m1) % (m1 * m2)) 18 | 19 | ll power(ll x, ll y, ll m) 20 | { 21 | if (y==0) return 1; 22 | ll p=power(x, y/2, m)%m; 23 | p=(p*p)%m; 24 | return (y%2==0)?p:(x*p)%m; 25 | } 26 | 27 | ll inverse(ll a, ll m) 28 | { 29 | return power(a, m-2, m); 30 | } 31 | 32 | void fft(vector & a, bool invert, ll mod, ll root, ll root_1) { 33 | ll n = a.size(); 34 | 35 | for (ll i = 1, j = 0; i < n; i++) { 36 | ll bit = n >> 1; 37 | for (; j & bit; bit >>= 1) 38 | j ^= bit; 39 | j ^= bit; 40 | 41 | if (i < j) 42 | swap(a[i], a[j]); 43 | } 44 | 45 | for (ll len = 2; len <= n; len <<= 1) { 46 | ll wlen = invert ? root_1 : root; 47 | for (ll i = len; i < root_pw; i <<= 1) 48 | wlen = (ll)(1LL * wlen * wlen % mod); 49 | 50 | for (ll i = 0; i < n; i += len) { 51 | ll w = 1; 52 | for (ll j = 0; j < len / 2; j++) { 53 | ll u = a[i+j], v = (ll)(1LL * a[i+j+len/2] * w % mod); 54 | a[i+j] = u + v < mod ? u + v : u + v - mod; 55 | a[i+j+len/2] = u - v >= 0 ? u - v : u - v + mod; 56 | w = (ll)(1LL * w * wlen % mod); 57 | } 58 | } 59 | } 60 | 61 | if (invert) { 62 | ll n_1 = inverse(n, mod); 63 | for (ll & x : a) 64 | x = (ll)(1LL * x * n_1 % mod); 65 | } 66 | } 67 | 68 | vector multiply(vector a, vector b, ll mod, ll root, ll root_1) { 69 | 70 | fft(a, false, mod, root, root_1); 71 | fft(b, false, mod, root, root_1); 72 | ll n=a.size(); 73 | for (ll i = 0; i < n; i++) 74 | a[i] = (1LL*a[i]*b[i])%mod; 75 | fft(a, true, mod, root, root_1); 76 | return a; 77 | } 78 | 79 | vector mul(vector a, vector b) { 80 | ll n = 1; 81 | while (n < a.size() + b.size()) 82 | n <<= 1; 83 | a.resize(n, 0); 84 | b.resize(n, 0); 85 | 86 | vector c0=multiply(a, b, mod0, root0, iroot0); 87 | vector c1=multiply(a, b, mod1, root1, iroot1); 88 | vector c(n); 89 | fr(i, n){ 90 | ll t = chinese(c0[i],mod0,c1[i],mod1); 91 | if (t < 0) t += 1LL*mod0*mod1; 92 | c[i] = t % mod; 93 | } 94 | return c; 95 | } -------------------------------------------------------------------------------- /cpp/Algebra/ntt.cpp: -------------------------------------------------------------------------------- 1 | //super-fast ntt taken from tourist 2 | 3 | const int mod = 998244353; 4 | 5 | inline void add(int &a, int b) { 6 | a += b; 7 | if (a >= mod) a -= mod; 8 | } 9 | inline void sub(int &a, int b) { 10 | a -= b; 11 | if (a < 0) a += mod; 12 | } 13 | inline int mul(int a, int b) { 14 | #if !defined(_WIN32) || defined(_WIN64) 15 | return (int) ((long long) a * b % mod); 16 | #endif 17 | unsigned long long x = (long long) a * b; 18 | unsigned xh = (unsigned) (x >> 32), xl = (unsigned) x, d, m; 19 | asm( 20 | "divl %4; \n\t" 21 | : "=a" (d), "=d" (m) 22 | : "d" (xh), "a" (xl), "r" (mod) 23 | ); 24 | return m; 25 | } 26 | 27 | 28 | inline int power(int a, long long b) { 29 | int res = 1; 30 | while (b > 0) { 31 | if (b & 1) { 32 | res = mul(res, a); 33 | } 34 | a = mul(a, a); 35 | b >>= 1; 36 | } 37 | return res; 38 | } 39 | inline int inv(int a) { 40 | a %= mod; 41 | if (a < 0) a += mod; 42 | int b = mod, u = 0, v = 1; 43 | while (a) { 44 | int t = b / a; 45 | b -= t * a; swap(a, b); 46 | u -= t * v; swap(u, v); 47 | } 48 | assert(b == 1); 49 | if (u < 0) u += mod; 50 | return u; 51 | } 52 | namespace ntt { 53 | int base = 1; 54 | vector roots = {0, 1}; 55 | vector rev = {0, 1}; 56 | int max_base = -1; 57 | int root = -1; 58 | void init() { 59 | int tmp = mod - 1; 60 | max_base = 0; 61 | while (tmp % 2 == 0) { 62 | tmp /= 2; 63 | max_base++; 64 | } 65 | root = 2; 66 | while (true) { 67 | if (power(root, 1 << max_base) == 1) { 68 | if (power(root, 1 << (max_base - 1)) != 1) { 69 | break; 70 | } 71 | } 72 | root++; 73 | } 74 | } 75 | void ensure_base(int nbase) { 76 | if (max_base == -1) { 77 | init(); 78 | } 79 | if (nbase <= base) { 80 | return; 81 | } 82 | assert(nbase <= max_base); 83 | rev.resize(1 << nbase); 84 | for (int i = 0; i < (1 << nbase); i++) { 85 | rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1)); 86 | } 87 | roots.resize(1 << nbase); 88 | while (base < nbase) { 89 | int z = power(root, 1 << (max_base - 1 - base)); 90 | for (int i = 1 << (base - 1); i < (1 << base); i++) { 91 | roots[i << 1] = roots[i]; 92 | roots[(i << 1) + 1] = mul(roots[i], z); 93 | } 94 | base++; 95 | } 96 | } 97 | void fft(vector &a) { 98 | int n = (int) a.size(); 99 | assert((n & (n - 1)) == 0); 100 | int zeros = __builtin_ctz(n); 101 | ensure_base(zeros); 102 | int shift = base - zeros; 103 | for (int i = 0; i < n; i++) { 104 | if (i < (rev[i] >> shift)) { 105 | swap(a[i], a[rev[i] >> shift]); 106 | } 107 | } 108 | for (int k = 1; k < n; k <<= 1) { 109 | for (int i = 0; i < n; i += 2 * k) { 110 | for (int j = 0; j < k; j++) { 111 | int x = a[i + j]; 112 | int y = mul(a[i + j + k], roots[j + k]); 113 | a[i + j] = x + y - mod; 114 | if (a[i + j] < 0) a[i + j] += mod; 115 | a[i + j + k] = x - y + mod; 116 | if (a[i + j + k] >= mod) a[i + j + k] -= mod; 117 | } 118 | } 119 | } 120 | } 121 | vector multiply(vector a, vector b, int eq = 0) { 122 | int need = (int) (a.size() + b.size() - 1); 123 | int nbase = 0; 124 | while ((1 << nbase) < need) nbase++; 125 | ensure_base(nbase); 126 | int sz = 1 << nbase; 127 | a.resize(sz); 128 | b.resize(sz); 129 | fft(a); 130 | if (eq) b = a; else fft(b); 131 | int inv_sz = inv(sz); 132 | for (int i = 0; i < sz; i++) { 133 | a[i] = mul(mul(a[i], b[i]), inv_sz); 134 | } 135 | reverse(a.begin() + 1, a.end()); 136 | fft(a); 137 | a.resize(need); 138 | return a; 139 | } 140 | vector square(vector a) { 141 | return multiply(a, a, 1); 142 | } 143 | } 144 | vi mult(vi a,vi b) { 145 | if (min(a.size(),b.size()) <= 5) { 146 | int sz1 = a.size(); 147 | int sz2 = b.size(); 148 | vi c(sz1 + sz2 - 1); 149 | for (int i = 0;i < sz1;++i) 150 | for (int j = 0;j < sz2;++j) 151 | add(c[i + j],mul(a[i],b[j])); 152 | return c; 153 | } else 154 | return ntt::multiply(a,b); 155 | } -------------------------------------------------------------------------------- /cpp/Algebra/online fft recursive.cpp: -------------------------------------------------------------------------------- 1 | //add contributions of ans[l->mid] to ans[mid+1->r] 2 | void solve(int l, int r) 3 | { 4 | if(l==r) return ; 5 | 6 | int m=(l+r)/2; 7 | solve(l, m); 8 | 9 | int sz=r-l+1; 10 | vi a(ans+l, ans+m+1), b(numtree+1, numtree+sz+1); 11 | vi c=mult(a, b); 12 | 13 | for(int i=m+1; i<=r; ++i) 14 | add(ans[i], c[i-l-1]); 15 | 16 | solve(m+1, r); 17 | return ; 18 | } -------------------------------------------------------------------------------- /cpp/Algebra/online fft.cpp: -------------------------------------------------------------------------------- 1 | //attributation: Tanuj Khattar's slides on online FFT 2 | //online FFT for solving recurrences of the form 3 | //F(i)=sum(1<=j= mod) a -= mod; 6 | } 7 | inline void sub(int &a, int b) { 8 | a -= b; 9 | if (a < 0) a += mod; 10 | } 11 | 12 | inline int mul(int a, int b) { 13 | #if !defined(_WIN32) || defined(_WIN64) 14 | return (int) ((long long) a * b % mod); 15 | #endif 16 | unsigned long long x = (long long) a * b; 17 | unsigned xh = (unsigned) (x >> 32), xl = (unsigned) x, d, m; 18 | asm( 19 | "divl %4; \n\t" 20 | : "=a" (d), "=d" (m) 21 | : "d" (xh), "a" (xl), "r" (mod) 22 | ); 23 | return m; 24 | } 25 | 26 | 27 | inline int power(int a, long long b) { 28 | int res = 1; 29 | while (b > 0) { 30 | if (b & 1) { 31 | res = mul(res, a); 32 | } 33 | a = mul(a, a); 34 | b >>= 1; 35 | } 36 | return res; 37 | } 38 | inline int inv(int a) { 39 | a %= mod; 40 | if (a < 0) a += mod; 41 | int b = mod, u = 0, v = 1; 42 | while (a) { 43 | int t = b / a; 44 | b -= t * a; swap(a, b); 45 | u -= t * v; swap(u, v); 46 | } 47 | assert(b == 1); 48 | if (u < 0) u += mod; 49 | return u; 50 | } 51 | 52 | //attribution: Jatin Yadav on codechef 53 | namespace fft{ 54 | #define ld double 55 | #define poly vector 56 | 57 | struct base{ 58 | ld x,y; 59 | base(){x=y=0;} 60 | base(ld _x, ld _y){x = _x,y = _y;} 61 | base(ld _x){x = _x, y = 0;} 62 | void operator = (ld _x){x = _x,y = 0;} 63 | ld real(){return x;} 64 | ld imag(){return y;} 65 | base operator + (const base& b){return base(x+b.x,y+b.y);} 66 | void operator += (const base& b){x+=b.x,y+=b.y;} 67 | base operator * (const base& b){return base(x*b.x - y*b.y,x*b.y+y*b.x);} 68 | void operator *= (const base& b){ld p = x*b.x - y*b.y, q = x*b.y+y*b.x; x = p, y = q;} 69 | void operator /= (ld k){x/=k,y/=k;} 70 | base operator - (const base& b){return base(x - b.x,y - b.y);} 71 | void operator -= (const base& b){x -= b.x, y -= b.y;} 72 | base conj(){ return base(x, -y);} 73 | base operator / (ld k) { return base(x / k, y / k);} 74 | void Print(){ cerr << x << " + " << y << "i\n";} 75 | }; 76 | double PI = 2.0*acos(0.0); 77 | const int MAXN = 17; 78 | const int maxn = 1<> 1; 95 | for (; j>=bit; bit>>=1) 96 | j -= bit; 97 | j += bit; 98 | if (i < j) 99 | swap (a[i], a[j]); 100 | } 101 | for (int len=2; len<=n; len<<=1) { 102 | for (int i=0; i upper_limit) c.resize(upper_limit); 168 | return c; 169 | } 170 | 171 | //attribution: https://www.codechef.com/viewsolution/19110694 172 | namespace poly_ops{ 173 | typedef ll base; 174 | inline int add(int x, int y){ x += y; if(x >= mod) x -= mod; return x;} 175 | inline int sub(int x, int y){ x -= y; if(x < 0) x += mod; return x;} 176 | 177 | poly truncate_end(poly v){ 178 | while(!v.empty() && v.back() == 0) v.pop_back(); 179 | if(v.empty()) v = {0}; 180 | return v; 181 | } 182 | 183 | poly add(poly a, poly b){ 184 | poly ret(max(a.size(), b.size())); 185 | for(int i = 0; i < (int)ret.size(); i++){ 186 | ret[i] = add(i < (int)a.size() ? a[i] : 0, i < (int)b.size() ? b[i] : 0); 187 | } 188 | return ret; 189 | } 190 | 191 | poly sub(poly a, poly b){ 192 | poly ret(max(a.size(), b.size())); 193 | for(int i = 0; i < (int)ret.size(); i++){ 194 | ret[i] = sub(i < (int)a.size() ? a[i] : 0, i < (int)b.size() ? b[i] : 0); 195 | } 196 | return ret; 197 | } 198 | 199 | poly mul_scalar(poly v, int k){ 200 | for(auto & it : v) it = mul(k, it); 201 | return v; 202 | } 203 | 204 | poly get_first(poly v, int k){ 205 | v.resize(min((int)v.size(), k)); 206 | return v; 207 | } 208 | 209 | poly inverse(poly a, int sz){ 210 | assert(a[0] != 0); 211 | poly x = {inv(a[0])}; 212 | while((int)x.size() < sz){ 213 | poly temp(a.begin(), a.begin() + min(a.size(), 2 * x.size())); 214 | poly nx = mult(mult(x, x), temp); 215 | x.resize(2 * x.size()); 216 | for(int i = 0; i < (int)x.size(); i++) 217 | x[i] = sub(add(x[i], x[i]), nx[i]); 218 | } 219 | x.resize(sz); 220 | return x; 221 | } 222 | 223 | poly differentiate(poly f){ 224 | for(int i = 0; i + 1 < (int)f.size(); i++) f[i] = mul(i + 1, f[i + 1]); 225 | if(!f.empty()) f.resize(f.size() - 1); 226 | if(f.empty()) f = {0}; 227 | return f; 228 | } 229 | 230 | poly integrate(poly f, int c = 0){ 231 | f.resize(f.size() + 1); 232 | for(int i = f.size(); i >= 1; i--) f[i] = mul(f[i - 1], inv(i)); 233 | f[0] = c; 234 | return f; 235 | } 236 | 237 | poly Log(poly f, int k){ 238 | assert(f[0] == 1); 239 | poly inv_f = inverse(f, k); 240 | return integrate(mult(differentiate(f), inv_f, k)) ; 241 | } 242 | 243 | poly Exp(poly f, int k){ 244 | assert(f[0] == 0); 245 | poly g = {1}; 246 | while((int)g.size() < k){ 247 | int curr_sz = g.size(); 248 | g = mult(g, get_first(add(f, sub({1}, Log(g, 2 * curr_sz))), 2 * curr_sz), 2 * curr_sz); 249 | } 250 | 251 | g.resize(k); 252 | return g; 253 | } 254 | 255 | poly powr(poly X, long long n, int k){ 256 | int common = X[0]; 257 | int inv_com = inv(common); 258 | X = mul_scalar(X, inv_com); 259 | n %= mod; 260 | poly ret = Exp(mul_scalar(Log(X, k + 1), n), k); 261 | ret.resize(k); 262 | ret = mul_scalar(ret, power(common, n)); 263 | return ret; 264 | } 265 | 266 | pair divmod(poly f, poly g){ 267 | if(f.size() < g.size()) return {{0}, f}; 268 | int sz = f.size() - g.size() + 1; 269 | reverse(f.begin(), f.end()); reverse(g.begin(), g.end()); 270 | poly inv2 = inverse(g, sz); 271 | poly _p = f; _p.resize(sz); 272 | poly q = mult(inv2, _p); 273 | q.resize(sz); 274 | reverse(q.begin(), q.end()); reverse(f.begin(), f.end()); reverse(g.begin(), g.end()); 275 | return {q, truncate_end(sub(f, mult(g, q)))}; 276 | } 277 | } -------------------------------------------------------------------------------- /cpp/Algebra/polynomial_interpolation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given n points (x[i], y[i]), computes an n-1-degree polynomial p that 3 | passes through them: p(x) = a[0]*x^0 + ... + a[n-1]*x^{n-1}. 4 | Time: O(n^2) 5 | To work modulo a prime, replace the divisions with modinverse 6 | */ 7 | typedef vector vd; 8 | vd interpolate(vd x, vd y) { 9 | int n=x.size(); 10 | vd res(n,0), temp(n,0); 11 | for(int k=0;k= 0$. 8 | * Returns -inf if there is no solution, inf if there are arbitrarily good solutions, or the maximum value of $c^T x$ otherwise. 9 | * The input vector is set to an optimal $x$ (or in the unbounded case, an arbitrary solution fulfilling the constraints). 10 | * Numerical stability is not guaranteed. For better performance, define variables such that $x = 0$ is viable. 11 | * Usage: 12 | * vvd A = {{1,-1}, {-1,1}, {-1,-2}}; 13 | * vd b = {1,1,-4}, c = {-1,-1}, x; 14 | * T val = LPSolver(A, b, c).solve(x); 15 | * Time: O(NM * \#pivots), where a pivot may be e.g. an edge relaxation. O(2^n) in the general case. 16 | * Status: seems to work? 17 | */ 18 | 19 | typedef long double DOUBLE; 20 | typedef vector VD; 21 | typedef vector VVD; 22 | typedef vector VI; 23 | 24 | const DOUBLE EPS = 1e-9; 25 | 26 | struct LPSolver { 27 | int m, n; 28 | VI B, N; 29 | VVD D; 30 | 31 | LPSolver(const VVD &A, const VD &b, const VD &c) : 32 | m(b.size()), n(c.size()), N(n + 1), B(m), D(m + 2, VD(n + 2)) { 33 | for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) D[i][j] = A[i][j]; 34 | for (int i = 0; i < m; i++) { B[i] = n + i; D[i][n] = -1; D[i][n + 1] = b[i]; } 35 | for (int j = 0; j < n; j++) { N[j] = j; D[m][j] = -c[j]; } 36 | N[n] = -1; D[m + 1][n] = 1; 37 | } 38 | 39 | void Pivot(int r, int s) { 40 | double inv = 1.0 / D[r][s]; 41 | for (int i = 0; i < m + 2; i++) if (i != r) 42 | for (int j = 0; j < n + 2; j++) if (j != s) 43 | D[i][j] -= D[r][j] * D[i][s] * inv; 44 | for (int j = 0; j < n + 2; j++) if (j != s) D[r][j] *= inv; 45 | for (int i = 0; i < m + 2; i++) if (i != r) D[i][s] *= -inv; 46 | D[r][s] = inv; 47 | swap(B[r], N[s]); 48 | } 49 | 50 | bool Simplex(int phase) { 51 | int x = phase == 1 ? m + 1 : m; 52 | while (true) { 53 | int s = -1; 54 | for (int j = 0; j <= n; j++) { 55 | if (phase == 2 && N[j] == -1) continue; 56 | if (s == -1 || D[x][j] < D[x][s] || D[x][j] == D[x][s] && N[j] < N[s]) s = j; 57 | } 58 | if (D[x][s] > -EPS) return true; 59 | int r = -1; 60 | for (int i = 0; i < m; i++) { 61 | if (D[i][s] < EPS) continue; 62 | if (r == -1 || D[i][n + 1] / D[i][s] < D[r][n + 1] / D[r][s] || 63 | (D[i][n + 1] / D[i][s]) == (D[r][n + 1] / D[r][s]) && B[i] < B[r]) r = i; 64 | } 65 | if (r == -1) return false; 66 | Pivot(r, s); 67 | } 68 | } 69 | 70 | DOUBLE Solve(VD &x) { 71 | int r = 0; 72 | for (int i = 1; i < m; i++) if (D[i][n + 1] < D[r][n + 1]) r = i; 73 | if (D[r][n + 1] < -EPS) { 74 | Pivot(r, n); 75 | if (!Simplex(1) || D[m + 1][n + 1] < -EPS) return -numeric_limits::infinity(); 76 | for (int i = 0; i < m; i++) if (B[i] == -1) { 77 | int s = -1; 78 | for (int j = 0; j <= n; j++) 79 | if (s == -1 || D[i][j] < D[i][s] || D[i][j] == D[i][s] && N[j] < N[s]) s = j; 80 | Pivot(i, s); 81 | } 82 | } 83 | if (!Simplex(2)) return numeric_limits::infinity(); 84 | x = VD(n); 85 | for (int i = 0; i < m; i++) if (B[i] < n) x[B[i]] = D[i][n + 1]; 86 | return D[m][n + 1]; 87 | } 88 | }; -------------------------------------------------------------------------------- /cpp/Algebra/strassens.cpp: -------------------------------------------------------------------------------- 1 | #include "bits/stdc++.h" 2 | 3 | using namespace std; 4 | 5 | typedef int base; 6 | typedef vector> matrix; 7 | 8 | matrix zero_matrix(int n, int m) 9 | { 10 | matrix ret(n); 11 | for (auto &i:ret) i.resize(m); 12 | return ret; 13 | } 14 | 15 | matrix submatrix(const matrix &mat, int i1, int i2, int j1, int j2) 16 | { 17 | matrix ans = zero_matrix(i2 - i1, j2 - j1); 18 | for (int i = i1; i < i2; i++) 19 | for (int j = j1; j < j2; j++) 20 | ans[i - i1][j - j1] = mat[i][j]; 21 | return ans; 22 | } 23 | 24 | 25 | matrix expand(const matrix &mat) 26 | { 27 | auto n = mat.size(); 28 | auto m = mat[0].size(); 29 | int t = 1; 30 | int p = max(n, m); 31 | 32 | while (t < p) 33 | t *= 2; 34 | p = t; 35 | matrix ans = zero_matrix(p, p); 36 | for (int i = 0; i < n; i++) 37 | for (int j = 0; j < m; j++) 38 | ans[i][j] = mat[i][j]; 39 | return ans; 40 | } 41 | 42 | void print(const matrix &grid) 43 | { 44 | for (int i = 0; i < grid.size(); i++){ 45 | for (int j = 0; j < grid[i].size(); j++) 46 | cout << grid[i][j] << ' '; 47 | cout << '\n'; 48 | } 49 | } 50 | 51 | matrix operator+(const matrix &a, const matrix &b) 52 | { 53 | matrix ans = zero_matrix(a.size(), a[0].size()); 54 | for (int i = 0; i < a.size(); i++) 55 | for (int j = 0; j < a[i].size(); j++) 56 | ans[i][j] = a[i][j] + b[i][j]; 57 | return ans; 58 | } 59 | 60 | matrix operator-(const matrix &a, const matrix &b) 61 | { 62 | matrix ans = zero_matrix(a.size(), a[0].size()); 63 | for (int i = 0; i < a.size(); i++) 64 | for (int j = 0; j < a[i].size(); j++) 65 | ans[i][j] = a[i][j] - b[i][j]; 66 | return ans; 67 | } 68 | 69 | matrix naive_multiply(const matrix &a, const matrix &b) 70 | { 71 | int s = 0; 72 | matrix ans = zero_matrix(a.size(), b[0].size()); 73 | for (int i = 0; i < a.size(); i++){ 74 | for (int j = 0; j < b[i].size(); j++){ 75 | s = 0; 76 | for (int k = 0; k < a[i].size(); k++) 77 | s += a[i][k] * b[k][j]; 78 | ans[i][j] = s; 79 | } 80 | } 81 | return ans; 82 | } 83 | 84 | 85 | matrix strassen(const matrix &m1, const matrix &m2) 86 | { 87 | int s1 = m1.size(); 88 | int s2 = m2.size(); 89 | if (s1 > 2 && s2 > 2){ 90 | matrix a = submatrix(m1, 0, s1 / 2, 0, s1/2), 91 | b = submatrix(m1, 0, s1 / 2, s1 / 2, s1), 92 | c = submatrix(m1, s1 / 2, s1, 0, s1 / 2), 93 | d = submatrix(m1, s1 / 2, s1, s1 / 2, s1), 94 | e = submatrix(m2, 0, s2 / 2, 0, s2/2), 95 | f = submatrix(m2, 0, s2 / 2, s2 / 2, s2), 96 | g = submatrix(m2, s2 / 2, s2, 0, s2 / 2), 97 | h = submatrix(m2, s2 / 2, s2, s2 / 2, s2), 98 | ans; 99 | 100 | 101 | matrix p1, p2, p3, p4, p5, p6, p7; 102 | p1 = strassen(a, f - h); 103 | p2 = strassen(a + b, h); 104 | p3 = strassen(c + d, e); 105 | p4 = strassen(d, g - e); 106 | p5 = strassen(a + d, e + h); 107 | p6 = strassen(b - d, g + h); 108 | p7 = strassen(a - c, e + f); 109 | matrix c1, c2, c3, c4; 110 | c1 = p5 + p4 + p6 - p2; 111 | c2 = p1 + p2; 112 | c3 = p3 + p4; 113 | c4 = p1 + p5 - p3 - p7; 114 | 115 | 116 | 117 | int flag1, flag2; 118 | for (int i = 0; i < m1.size(); i++){ 119 | vector row; 120 | if (i < m1.size() / 2) 121 | flag1 = 0; 122 | else 123 | flag1 = 1; 124 | for (int j = 0; j < m2[i].size(); j++) 125 | if (j < m2[i].size() / 2) 126 | if (flag1 == 0) row.push_back(c1[i][j]); 127 | else row.push_back(c3[i - m1.size() / 2][j]); 128 | else 129 | if (flag1 == 0) row.push_back(c2[i][j - m2[i].size() / 2]); 130 | else row.push_back(c4[i - m1.size() / 2][j - m2[i].size() / 2]); 131 | ans.push_back(row); 132 | } 133 | return ans; 134 | } 135 | return naive_multiply(m1, m2); 136 | } 137 | 138 | int main() 139 | { 140 | matrix v1, v2, v3; 141 | 142 | matrix matrix1 = { 143 | {1, 2, 3, 4}, 144 | {5, 6, 7, 8}, 145 | {9, 10, 11, 12}, 146 | {1, 2, 3, 4}, 147 | {5, 6, 7, 8}, 148 | {9, 10, 11, 12} 149 | }; //4*6 matrix 150 | matrix matrix2 = { 151 | {13, 14, 15, 13, 14, 15}, 152 | {16, 17, 18, 16, 17, 18}, 153 | {19, 20, 21, 19, 20, 21}, 154 | {22, 23, 24, 22, 23, 24} 155 | }; //6*4 matrix 156 | 157 | matrix m1, m2, m3, m4; 158 | m1 = expand(matrix1); 159 | m2 = expand(matrix2); 160 | 161 | v1 = submatrix(naive_multiply(m1, m2), 0, matrix1.size(), 0, matrix2[0].size()); 162 | 163 | 164 | print(v1); 165 | cout << '\n'; 166 | 167 | v2 = submatrix(strassen(m1, m2), 0, matrix1.size(), 0, matrix2[0].size()); 168 | print(v2); 169 | 170 | return 0; 171 | } -------------------------------------------------------------------------------- /cpp/Algebra/xor3.cpp: -------------------------------------------------------------------------------- 1 | ll xor3(ll a, ll b) 2 | { 3 | ll ans=0, three=1, trm; 4 | while(a|b){ 5 | trm=(a+b)%3; 6 | ans+=trm*three; 7 | three*=3; 8 | a/=3; 9 | b/=3; 10 | } 11 | return ans%p2; 12 | } 13 | 14 | ll dxor3(ll a, ll b) 15 | { 16 | ll ans=0, three=1, trm; 17 | while(a|b){ 18 | trm=((a-b)%3+3)%3; 19 | ans+=trm*three; 20 | three*=3; 21 | a/=3; 22 | b/=3; 23 | } 24 | return ans%p2; 25 | } -------------------------------------------------------------------------------- /cpp/Data Structures/128bit.cpp: -------------------------------------------------------------------------------- 1 | std::ostream& 2 | operator<<( std::ostream& dest, __int128_t value ) 3 | { 4 | std::ostream::sentry s( dest ); 5 | if ( s ) { 6 | __uint128_t tmp = value < 0 ? -value : value; 7 | char buffer[ 128 ]; 8 | char* d = std::end( buffer ); 9 | do 10 | { 11 | -- d; 12 | *d = "0123456789"[ tmp % 10 ]; 13 | tmp /= 10; 14 | } while ( tmp != 0 ); 15 | if ( value < 0 ) { 16 | -- d; 17 | *d = '-'; 18 | } 19 | int len = std::end( buffer ) - d; 20 | if ( dest.rdbuf()->sputn( d, len ) != len ) { 21 | dest.setstate( std::ios_base::badbit ); 22 | } 23 | } 24 | return dest; 25 | } -------------------------------------------------------------------------------- /cpp/Data Structures/dsu.cpp: -------------------------------------------------------------------------------- 1 | struct DSU{ 2 | int n, components; 3 | vi par, sz; 4 | int root(int x) 5 | { return x==par[x]?x:(par[x]=root(par[x])); } 6 | bool merge(int x1, int x2) 7 | { 8 | x1=root(x1), x2=root(x2); 9 | if(x1==x2) return false; 10 | if(sz[x2]>sz[x1]) swap(x1, x2); 11 | par[x2]=x1; sz[x1]+=sz[x2]; 12 | --components; 13 | return true; 14 | } 15 | DSU(int _n) 16 | { 17 | n=components=_n; 18 | sz.assign(n+1, 1); 19 | par.resize(n+1); 20 | iota(all(par), 0); 21 | } 22 | }; -------------------------------------------------------------------------------- /cpp/Data Structures/dsu_with_rollback.cpp: -------------------------------------------------------------------------------- 1 | struct DSU{ 2 | int n, components; 3 | vi par, sz; 4 | vector stak; 5 | 6 | DSU(int _n) 7 | { 8 | n=components=_n; 9 | sz.assign(n+1, 1); 10 | par.resize(n+1); 11 | iota(all(par), 0); 12 | } 13 | 14 | int root(int x) 15 | { 16 | while (x != par[x]) { 17 | x = par[x]; 18 | } 19 | return x; 20 | } 21 | 22 | int getVersion() 23 | { 24 | return stak.size(); 25 | } 26 | 27 | void rollback(int target) 28 | { 29 | assert(target <= stak.size()); 30 | while (stak.size() > target) { 31 | int a = stak.back().ff, b = stak.back().ss; 32 | stak.pop_back(); 33 | ++components; 34 | sz[a] -= sz[b]; 35 | par[b] = b; 36 | } 37 | } 38 | 39 | bool merge(int x1, int x2) 40 | { 41 | x1 = root(x1), x2 = root(x2); 42 | if(x1==x2) { 43 | return false; 44 | } 45 | if(sz[x2]>sz[x1]) 46 | swap(x1, x2); 47 | stak.pb({x1, x2}); 48 | par[x2]=x1; sz[x1]+=sz[x2]; 49 | --components; 50 | return true; 51 | } 52 | }; -------------------------------------------------------------------------------- /cpp/Data Structures/implicit treap.cpp: -------------------------------------------------------------------------------- 1 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 2 | 3 | struct node{ 4 | int prior=rng(), val, size=1; 5 | node *l=0, *r=0; 6 | node(int v):val(v) 7 | { 8 | // write code to initialize custom fields 9 | } 10 | }; 11 | 12 | typedef node* pnode; 13 | 14 | #define sz(t) (t?t->size:0) 15 | 16 | inline void update(pnode t) 17 | { 18 | if(!t) return; 19 | t->size = sz(t->l)+1+sz(t->r); 20 | // write code to find values of custorm fields ot t using it's children 21 | } 22 | 23 | // puts first key values in l, rest in r 24 | inline void split(pnode t,pnode &l,pnode &r, int key, int add=0) 25 | { 26 | if(!t) return void(l=r=0); 27 | int cur_key=add+sz(t->l); 28 | if(key<=cur_key) split(t->l, l, t->l, key, add), r=t; 29 | else split(t->r, t->r, r, key, add+1+sz(t->l)), l=t; 30 | update(t); 31 | } 32 | 33 | // merge l and r, store result in t 34 | inline void merge(pnode &t, pnode l, pnode r) 35 | { 36 | if(!l) t=r; 37 | else if(!r) t=l; 38 | else if(l->prior>r->prior) merge(l->r, l->r, r), t=l; 39 | else merge(r->l, l, r->l), t=r; 40 | update(t); 41 | } 42 | 43 | // runs a dfs to print treap 44 | void disp(pnode root) 45 | { 46 | if(!root) return ; 47 | disp(root->l); cout<val<<" "; disp(root->r); 48 | return ; 49 | } 50 | 51 | // insert before index pos, 0 based 52 | inline void insert(pnode &t, pnode &x, int pos) 53 | { 54 | if(!t) return void(t=x); 55 | pnode t1=0, t2=0; 56 | split(t, t1, t2, pos); 57 | merge(t1, t1, x); 58 | merge(t, t1, t2); 59 | } 60 | 61 | inline void erase(pnode &t, int pos) 62 | { 63 | if(!t) return ; 64 | if(sz(t->l)+1==pos) {node *tmp=t; merge(t, t->l, t->r); free(tmp);} 65 | else if(pos<=sz(t->l)) erase(t->l, pos); 66 | else erase(t->r, pos-sz(t->l)-1); 67 | } 68 | 69 | // pnode root=0; -------------------------------------------------------------------------------- /cpp/Data Structures/non-overlapping intervals.cpp: -------------------------------------------------------------------------------- 1 | void insert(set &s, pii cur) 2 | { 3 | auto it=s.upper_bound(cur); 4 | vpii rem; 5 | if(it!=s.end() && it->ff==cur.ss+1){ 6 | cur.ss=it->ss; 7 | rem.pb(*it); 8 | } 9 | if(it!=s.begin()){ 10 | --it; 11 | if(it->ss+1==cur.ff){ 12 | cur.ff=it->ff; 13 | rem.pb(*it); 14 | } 15 | } 16 | for(auto i:rem) 17 | s.erase(i); 18 | s.insert(cur); 19 | } 20 | 21 | void erase(set &s, pii cur) 22 | { 23 | auto it=s.upper_bound(cur); 24 | --it; 25 | pii tmp=*it; 26 | s.erase(it); 27 | if(tmp.ffcur.ss) s.insert({cur.ss+1, tmp.ss}); 29 | } -------------------------------------------------------------------------------- /cpp/Data Structures/order statistics tree.cpp: -------------------------------------------------------------------------------- 1 | #include // Common file 2 | #include // Including tree_order_statistics_node_update 3 | 4 | using namespace __gnu_pbds; 5 | typedef tree, rb_tree_tag, tree_order_statistics_node_update> oset; 6 | typedef tree, rb_tree_tag, tree_order_statistics_node_update> omap; 7 | 8 | /* 9 | functions: 10 | 1)insert() 11 | 2)find_by_order(x) returns iterator to xth smallest element 12 | 3)order_of_key(x) return no of elems less than x 13 | 4)erase(number) 14 | */ -------------------------------------------------------------------------------- /cpp/Data Structures/persistent trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define all(x) x.begin(),x.end() 3 | #define mp(x,y) make_pair(x,y) 4 | #define pb(x) push_back(x) 5 | #define pf(x) push_front(x) 6 | #define ppb(x) pop_back(x) 7 | #define ppf(x) pop_front(x) 8 | #define clr(a,b) memset(a,b,sizeof a) 9 | #define ff first 10 | #define ss second 11 | #define umap unordered_map 12 | #define fr(i,n) for(int i=0;i pii; 23 | typedef pair pli; 24 | typedef pair pil; 25 | typedef pair pll; 26 | typedef pair pdd; 27 | typedef vector vi; 28 | typedef vector vl; 29 | typedef vector vc; 30 | typedef vector vll; 31 | typedef vector vb; 32 | typedef vector vd; 33 | 34 | /*primes*/ 35 | //ll p1=1e6+3, p2=1616161, p3=3959297, p4=7393931; 36 | //freopen("in.txt" , "r" , stdin) ; 37 | //freopen("out.txt" , "w" , stdout) ; 38 | 39 | int n, q, num, tkn=0; 40 | 41 | struct Node { 42 | int f; 43 | Node* child[2] = {}; 44 | Node() : f(0) {} 45 | }; 46 | 47 | vector roots; 48 | 49 | void init() 50 | { 51 | roots.resize(n+1); 52 | roots[0] = new Node; 53 | } 54 | 55 | int cans; 56 | 57 | typedef Node* pnode; 58 | 59 | int tf(pnode cur) 60 | { 61 | if(!cur) return 0; 62 | return cur->f; 63 | } 64 | 65 | void insert(pnode &naya, pnode purana, int lvl) 66 | { 67 | if(lvl==-1){ 68 | naya->f=tf(purana)+1; 69 | return ; 70 | } 71 | if((1<child[1] = new Node; 73 | naya->child[0]=(purana?purana->child[0]:NULL); 74 | 75 | if(purana) purana=purana->child[1]; 76 | insert(naya->child[1], purana, lvl-1); 77 | naya->f=tf(naya->child[0])+tf(naya->child[1]); 78 | return ; 79 | } 80 | naya->child[0] = new Node; 81 | naya->child[1]=(purana?purana->child[1]:NULL); 82 | 83 | if(purana) purana=purana->child[0]; 84 | insert(naya->child[0], purana, lvl-1); 85 | naya->f=tf(naya->child[0])+tf(naya->child[1]); 86 | return ; 87 | } 88 | 89 | void maxpos(pnode l, pnode r, int lvl) 90 | { 91 | if(lvl==-1) return ; 92 | int cur=0; 93 | if((1<child[0]); 95 | if(l) cur-=tf(l->child[0]); 96 | if(cur){ 97 | cans|=(1<child[0]; 99 | if(r) r=r->child[0]; 100 | maxpos(l, r, lvl-1); 101 | } 102 | else{ 103 | if(l) l=l->child[1]; 104 | if(r) r=r->child[1]; 105 | maxpos(l, r, lvl-1); 106 | } 107 | } 108 | else{ 109 | if(r) cur+=tf(r->child[1]); 110 | if(l) cur-=tf(l->child[1]); 111 | if(cur){ 112 | cans|=(1<child[1]; 114 | if(r) r=r->child[1]; 115 | maxpos(l, r, lvl-1); 116 | } 117 | else{ 118 | if(l) l=l->child[0]; 119 | if(r) r=r->child[0]; 120 | maxpos(l, r, lvl-1); 121 | } 122 | } 123 | return ; 124 | } 125 | 126 | int main() 127 | { 128 | ios_base::sync_with_stdio(false); 129 | cin.tie(0); 130 | int t; 131 | cin>>t; 132 | while(t--){ 133 | cin>>n>>q; 134 | init(); 135 | 136 | int x; 137 | fr1(i, n){ 138 | cin>>num; 139 | roots[i] = new Node; 140 | insert(roots[i], roots[i-1], 14); 141 | } 142 | 143 | int l, r; 144 | fr(i, q){ 145 | cin>>num>>l>>r; 146 | cans=0; 147 | maxpos(roots[l-1], roots[r], 14); 148 | cout< 3 | struct RMQ { 4 | int n = 0, levels = 0; 5 | vector> range_min; 6 | 7 | RMQ(const vector &values = {}) { 8 | if (!values.empty()) 9 | build(values); 10 | } 11 | 12 | static int largest_bit(int x) { 13 | return 31 - __builtin_clz(x); 14 | } 15 | 16 | static T better(T a, T b) { 17 | return maximum_mode ? max(a, b) : min(a, b); 18 | } 19 | 20 | void build(const vector &values) { 21 | n = values.size(); 22 | levels = largest_bit(n) + 1; 23 | range_min.resize(levels); 24 | 25 | for (int k = 0; k < levels; k++) 26 | range_min[k].resize(n - (1 << k) + 1); 27 | 28 | if (n > 0) 29 | range_min[0] = values; 30 | 31 | for (int k = 1; k < levels; k++) 32 | for (int i = 0; i <= n - (1 << k); i++) 33 | range_min[k][i] = better(range_min[k - 1][i], range_min[k - 1][i + (1 << (k - 1))]); 34 | } 35 | 36 | T query_value(int a, int b) const { 37 | assert(0 <= a && a <= b && b < n); 38 | int level = largest_bit(b - a + 1); 39 | return better(range_min[level][a], range_min[level][b + 1 - (1 << level)]); 40 | } 41 | }; -------------------------------------------------------------------------------- /cpp/Data Structures/segtree with pointers.cpp: -------------------------------------------------------------------------------- 1 | struct node{ 2 | node *l=0, *r=0; 3 | int val=0; 4 | }; 5 | 6 | typedef node* pnode; 7 | 8 | inline void build(int st, int en, pnode &cur) 9 | { 10 | cur=new node; 11 | if(st==en){ 12 | cur.val=arr[st]; 13 | return ; 14 | } 15 | int mid=(st+en)>>1; 16 | build(st, mid, cur->l); 17 | build(mid+1, en, cur->r); 18 | cur.val=cur->l->val+cur->r->val; 19 | } 20 | 21 | #define valf(x) (x?x->val:0) 22 | 23 | inline void update(int st, int en, pnode &cur, int idx, int nv) 24 | { 25 | if(st>idx || enval+=nv; 29 | return ; 30 | } 31 | int mid=(st+en)>>1; 32 | if(idx<=mid) update(st, mid, cur->l, idx, nv); 33 | else update(mid+1, en, cur->r, idx, nv); 34 | cur->val=valf(cur->l)+valf(cur->r); 35 | } 36 | 37 | inline int query(int st, int en, pnode cur, int l, int r) 38 | { 39 | if(st>r || en=l && en<=r) return cur->val; 41 | int mid=(st+en)>>1; 42 | return query(st, mid, cur->l, l, r)+query(mid+1, en, cur->r, l, r); 43 | } 44 | 45 | //lazy propogation 46 | // Attribution: https://codeforces.com/contest/1469/submission/102594210 47 | 48 | struct Node { 49 | Node* l = 0; Node* r = 0; 50 | ll L, R; 51 | ll sum, lazy; 52 | 53 | Node(ll X, ll Y) { 54 | L = X; R = Y; 55 | sum = 0; lazy = 0; 56 | } 57 | 58 | void initChildren() { 59 | int mid = (L + R) >> 1; 60 | l = new Node(L, mid); 61 | r = new Node(mid + 1, R); 62 | } 63 | 64 | void push() { 65 | sum = sum + lazy * (R - L + 1); 66 | if (L != R && lazy != 0) { 67 | if (!l) initChildren(); 68 | l->lazy += lazy; r->lazy += lazy; 69 | } 70 | lazy = 0; 71 | } 72 | 73 | void pull() { 74 | if (L != R && l) sum = l->sum + r->sum; 75 | } 76 | 77 | ll query(int lo, int hi) { 78 | if (hi < L || lo > R) return 0; 79 | push(); 80 | if (lo >= L && hi <= R) return sum; 81 | if (!l) initChildren(); 82 | return l->query(lo, hi) + r->query(lo, hi); 83 | } 84 | 85 | void update(int lo, int hi, ll del) { 86 | push(); 87 | if (hi < L || R < lo) return; 88 | if (lo <= L && R <= hi) { 89 | lazy = del; 90 | push(); 91 | return; 92 | } 93 | if (l == NULL) initChildren(); 94 | l->update(lo, hi, del); 95 | r->update(lo, hi, del); 96 | pull(); 97 | } 98 | }; -------------------------------------------------------------------------------- /cpp/Data Structures/segtree.cpp: -------------------------------------------------------------------------------- 1 | struct Segtree { 2 | typedef int base; 3 | typedef int qbase; 4 | int L, R; 5 | vector tree; 6 | 7 | inline base unite(base n1, base n2) 8 | { 9 | return n1 + n2; 10 | } 11 | 12 | inline void build(int st, int en, int node) 13 | { 14 | if (st == en) { 15 | tree[node] = vec[st]; 16 | return ; 17 | } 18 | 19 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 20 | 21 | build(st, mid, cl); 22 | build(mid + 1, en, cr); 23 | 24 | tree[node] = unite(tree[cl], tree[cr]); 25 | } 26 | 27 | Segtree(int l, int r) : L(l), R(r) 28 | { 29 | tree.resize((R - L + 1) << 2, 0); 30 | build(L, R, 1); 31 | } 32 | 33 | inline void update(int st, int en, int node, int idx, base nv) 34 | { 35 | if (st > idx || en < idx) return ; 36 | 37 | if (st == en) { 38 | tree[node] += nv; 39 | return ; 40 | } 41 | 42 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 43 | 44 | update(st, mid, cl, idx, nv); 45 | update(mid + 1, en, cr, idx, nv); 46 | 47 | tree[node] = unite(tree[cl], tree[cr]); 48 | } 49 | 50 | inline qbase query(int st, int en, int node, int l, int r) 51 | { 52 | if (st >= l && en <= r) return tree[node]; 53 | 54 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 55 | 56 | if (r <= mid) return query(st, mid, cl, l, r); 57 | if (l > mid) return query(mid + 1, en, cr, l, r); 58 | return query(st, mid, cl, l, r) + query(mid + 1, en, cr, l, r); 59 | } 60 | 61 | void dfs(int st, int en, int node) 62 | { 63 | if (st == en) { 64 | trace(st, tree[node]); 65 | return ; 66 | } 67 | 68 | trace(st, en, tree[node]); 69 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 70 | dfs(st, mid, cl); 71 | dfs(mid + 1, en, cr); 72 | } 73 | 74 | void show() 75 | { 76 | dfs(L, R, 1); 77 | } 78 | 79 | qbase query(int l, int r) { return query(L, R, 1, l, r); } 80 | 81 | void update(int idx, base nv) 82 | { 83 | update(L, R, 1, idx, nv); 84 | } 85 | }; 86 | 87 | 88 | 89 | //lazy propogation 90 | 91 | struct Segtree { 92 | typedef int base; 93 | typedef int qbase; 94 | int L, R; 95 | vector tree; 96 | vector lazy; 97 | 98 | inline base unite(base n1, base n2) 99 | { 100 | return n1 + n2; 101 | } 102 | 103 | inline void build(int st, int en, int node) 104 | { 105 | if (st == en) { 106 | tree[node] = vec[st]; 107 | return ; 108 | } 109 | 110 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 111 | build(st, mid, cl); 112 | build(mid + 1, en, cr); 113 | tree[node] = unite(tree[cl], tree[cr]); 114 | } 115 | 116 | Segtree(int l, int r) : L(l), R(r) 117 | { 118 | tree.resize((R - L + 1) << 2, 0); 119 | lazy.resize((R - L + 1) << 2, 0); 120 | build(L, R, 1); 121 | } 122 | 123 | inline void push(int st, int en, int node) 124 | { 125 | tree[node] += (en - st + 1) * lazy[node]; 126 | if (st != en) { 127 | int cl = (node << 1), cr = (cl | 1); 128 | lazy[cl] += lazy[node]; 129 | lazy[cr] += lazy[node]; 130 | } 131 | lazy[node] = 0; 132 | } 133 | 134 | inline void update(int st, int en, int node, int l, int r, base nv) 135 | { 136 | if (lazy[node]) push(st, en, node); 137 | if (st>r || en= l && en <= r) { 140 | lazy[node] = nv; 141 | push(st, en, node); 142 | return ; 143 | } 144 | 145 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 146 | 147 | update(st, mid, cl, l, r, nv); 148 | update(mid + 1, en, cr, l, r, nv); 149 | tree[node] = unite(tree[cl], tree[cr]); 150 | } 151 | 152 | inline qbase query(int st, int en, int node, int l, int r) 153 | { 154 | if (lazy[node]) push(st, en, node); 155 | if (st > r || en < l) return 0; 156 | if (st >= l && en <= r) return tree[node]; 157 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 158 | return query(st, mid, cl, l, r) + query(mid + 1, en, cr, l, r); 159 | } 160 | 161 | void dfs(int st, int en, int node) 162 | { 163 | if (lazy[node]) push(st, en, node); 164 | if (st == en) { 165 | trace(st, tree[node]); 166 | return ; 167 | } 168 | 169 | trace(st, en, tree[node]); 170 | int mid = (st + en) >> 1, cl = (node << 1), cr = (cl | 1); 171 | dfs(st, mid, cl); 172 | dfs(mid + 1, en, cr); 173 | } 174 | 175 | void update(int l, int r, base nv) 176 | { 177 | update(L, R, 1, l, r, nv); 178 | } 179 | 180 | qbase query(int l, int r) 181 | { 182 | return query(L, R, 1, l, r); 183 | } 184 | 185 | void show() 186 | { 187 | dfs(L, R, 1); 188 | } 189 | }; 190 | -------------------------------------------------------------------------------- /cpp/Data Structures/serach_buckets.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Atribution: Neal Wu, https://codeforces.com/contest/1093/submission/47229079 3 | search_buckets provides two operations on an array: 4 | 1) set array[i] = x 5 | 2) count how many i in [start, end) satisfy array[i] < value 6 | Both operations take sqrt(N log N) time. Amazingly, because of the cache efficiency this is faster than the 7 | (log N)^2 algorithm until N = 2-5 million. 8 | */ 9 | 10 | template 11 | struct search_buckets { 12 | // values are just the values in order. buckets are sorted in segments of BUCKET_SIZE (last segment may be smaller) 13 | int N, BUCKET_SIZE; 14 | vector values, buckets; 15 | 16 | search_buckets(const vector &initial = {}) { 17 | init(initial); 18 | } 19 | 20 | int get_bucket_end(int bucket_start) const { 21 | return min(bucket_start + BUCKET_SIZE, N); 22 | } 23 | 24 | void init(const vector &initial) { 25 | values = buckets = initial; 26 | N = values.size(); 27 | BUCKET_SIZE = 3 * sqrt(N * log(N + 1)) + 1; 28 | cerr << "Bucket size: " << BUCKET_SIZE << endl; 29 | 30 | for (int start = 0; start < N; start += BUCKET_SIZE) 31 | sort(buckets.begin() + start, buckets.begin() + get_bucket_end(start)); 32 | } 33 | 34 | int bucket_less_than(int bucket_start, T value) const { 35 | auto begin = buckets.begin() + bucket_start; 36 | auto end = buckets.begin() + get_bucket_end(bucket_start); 37 | return lower_bound(begin, end, value) - begin; 38 | } 39 | 40 | int less_than(int start, int end, T value) const { 41 | int count = 0; 42 | int bucket_start = start - start % BUCKET_SIZE; 43 | int bucket_end = min(get_bucket_end(bucket_start), end); 44 | 45 | if (start - bucket_start < bucket_end - start) { 46 | while (start > bucket_start) 47 | count -= values[--start] < value; 48 | } else { 49 | while (start < bucket_end) 50 | count += values[start++] < value; 51 | } 52 | 53 | if (start == end) 54 | return count; 55 | 56 | bucket_start = end - end % BUCKET_SIZE; 57 | bucket_end = get_bucket_end(bucket_start); 58 | 59 | if (end - bucket_start < bucket_end - end) { 60 | while (end > bucket_start) 61 | count += values[--end] < value; 62 | } else { 63 | while (end < bucket_end) 64 | count -= values[end++] < value; 65 | } 66 | 67 | while (start < end && get_bucket_end(start) <= end) { 68 | count += bucket_less_than(start, value); 69 | start = get_bucket_end(start); 70 | } 71 | 72 | assert(start == end); 73 | return count; 74 | } 75 | 76 | int prefix_less_than(int n, T value) const { 77 | return less_than(0, n, value); 78 | } 79 | 80 | void modify(int index, T value) { 81 | int bucket_start = index - index % BUCKET_SIZE; 82 | int old_pos = bucket_start + bucket_less_than(bucket_start, values[index]); 83 | int new_pos = bucket_start + bucket_less_than(bucket_start, value); 84 | 85 | if (old_pos < new_pos) { 86 | copy(buckets.begin() + old_pos + 1, buckets.begin() + new_pos, buckets.begin() + old_pos); 87 | new_pos--; 88 | // memmove(&buckets[old_pos], &buckets[old_pos + 1], (new_pos - old_pos) * sizeof(T)); 89 | } else { 90 | copy_backward(buckets.begin() + new_pos, buckets.begin() + old_pos, buckets.begin() + old_pos + 1); 91 | // memmove(&buckets[new_pos + 1], &buckets[new_pos], (old_pos - new_pos) * sizeof(T)); 92 | } 93 | 94 | buckets[new_pos] = value; 95 | values[index] = value; 96 | } 97 | }; -------------------------------------------------------------------------------- /cpp/Data Structures/splay tree.cpp: -------------------------------------------------------------------------------- 1 | //attribution: https://codeforces.com/contest/899/submission/44463457?locale=en 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class node { 8 | public: 9 | int id; 10 | node* l; 11 | node* r; 12 | node* p; 13 | bool rev; 14 | int sz; 15 | // declare extra variables: 16 | 17 | 18 | node(int _id) { 19 | id = _id; 20 | l = r = p = NULL; 21 | rev = false; 22 | sz = 1; 23 | // init extra variables: 24 | 25 | } 26 | 27 | void unsafe_reverse() { 28 | rev ^= 1; 29 | swap(l, r); 30 | pull(); 31 | } 32 | 33 | // apply changes: 34 | void unsafe_apply() { 35 | 36 | } 37 | 38 | void push() { 39 | if (rev) { 40 | if (l != NULL) { 41 | l->unsafe_reverse(); 42 | } 43 | if (r != NULL) { 44 | r->unsafe_reverse(); 45 | } 46 | rev = 0; 47 | } 48 | // now push everything else: 49 | 50 | } 51 | 52 | void pull() { 53 | sz = 1; 54 | // now init from self: 55 | 56 | if (l != NULL) { 57 | l->p = this; 58 | sz += l->sz; 59 | // now pull from l: 60 | 61 | } 62 | if (r != NULL) { 63 | r->p = this; 64 | sz += r->sz; 65 | // now pull from r: 66 | 67 | } 68 | } 69 | }; 70 | 71 | void debug_node(node* v, string pref = "") { 72 | #ifdef LOCAL 73 | if (v != NULL) { 74 | debug_node(v->r, pref + " "); 75 | cerr << pref << "-" << " " << v->id << '\n'; 76 | debug_node(v->l, pref + " "); 77 | } else { 78 | cerr << pref << "-" << " " << "NULL" << '\n'; 79 | } 80 | #endif 81 | } 82 | 83 | namespace splay_tree { 84 | bool is_bst_root(node* v) { 85 | if (v == NULL) { 86 | return false; 87 | } 88 | return (v->p == NULL || (v->p->l != v && v->p->r != v)); 89 | } 90 | 91 | void rotate(node* v) { 92 | node* u = v->p; 93 | assert(u != NULL); 94 | u->push(); 95 | v->push(); 96 | v->p = u->p; 97 | if (v->p != NULL) { 98 | if (v->p->l == u) { 99 | v->p->l = v; 100 | } 101 | if (v->p->r == u) { 102 | v->p->r = v; 103 | } 104 | } 105 | if (v == u->l) { 106 | u->l = v->r; 107 | v->r = u; 108 | } else { 109 | u->r = v->l; 110 | v->l = u; 111 | } 112 | u->pull(); 113 | v->pull(); 114 | } 115 | 116 | void splay(node* v) { 117 | if (v == NULL) { 118 | return; 119 | } 120 | while (!is_bst_root(v)) { 121 | node* u = v->p; 122 | if (!is_bst_root(u)) { 123 | if ((u->l == v) ^ (u->p->l == u)) { 124 | rotate(v); 125 | } else { 126 | rotate(u); 127 | } 128 | } 129 | rotate(v); 130 | } 131 | } 132 | 133 | pair find(node* v, const function &go_to) { 134 | // go_to returns: 0 -- found; -1 -- go left; 1 -- go right 135 | // find returns the last vertex on the descent and its go_to 136 | if (v == NULL) { 137 | return {NULL, 0}; 138 | } 139 | splay(v); 140 | int dir; 141 | while (true) { 142 | v->push(); 143 | dir = go_to(v); 144 | if (dir == 0) { 145 | break; 146 | } 147 | node* u = (dir == -1 ? v->l : v->r); 148 | if (u == NULL) { 149 | break; 150 | } 151 | v = u; 152 | } 153 | splay(v); 154 | return {v, dir}; 155 | } 156 | 157 | node* get_leftmost(node* v) { 158 | return find(v, [&](node*) { return -1; }).first; 159 | } 160 | 161 | node* get_rightmost(node* v) { 162 | return find(v, [&](node*) { return 1; }).first; 163 | } 164 | 165 | node* get_kth(node* v, int k) { // 0-indexed 166 | pair p = find(v, [&](node* u) { 167 | if (u->l != NULL) { 168 | if (u->l->sz > k) { 169 | return -1; 170 | } 171 | k -= u->l->sz; 172 | } 173 | if (k == 0) { 174 | return 0; 175 | } 176 | k--; 177 | return 1; 178 | }); 179 | return (p.second == 0 ? p.first : NULL); 180 | } 181 | 182 | int get_position(node* v) { // 0-indexed 183 | splay(v); 184 | return (v->l != NULL ? v->l->sz : 0); 185 | } 186 | 187 | node* get_bst_root(node* v) { 188 | splay(v); 189 | return v; 190 | } 191 | 192 | pair split(node* v, const function &is_right) { 193 | if (v == NULL) { 194 | return {NULL, NULL}; 195 | } 196 | pair p = find(v, [&](node* u) { return is_right(u) ? -1 : 1; }); 197 | v = p.first; 198 | v->push(); 199 | if (p.second == -1) { 200 | node* u = v->l; 201 | if (u == NULL) { 202 | return {NULL, v}; 203 | } 204 | v->l = NULL; 205 | u->p = v->p; 206 | u = get_rightmost(u); 207 | v->p = u; 208 | v->pull(); 209 | return {u, v}; 210 | } else { 211 | node* u = v->r; 212 | if (u == NULL) { 213 | return {v, NULL}; 214 | } 215 | v->r = NULL; 216 | v->pull(); 217 | return {v, u}; 218 | } 219 | } 220 | 221 | pair split_leftmost_k(node* v, int k) { 222 | return split(v, [&](node* u) { 223 | int left_and_me = (u->l != NULL ? u->l->sz : 0) + 1; 224 | if (k >= left_and_me) { 225 | k -= left_and_me; 226 | return false; 227 | } 228 | return true; 229 | }); 230 | } 231 | 232 | node* merge(node* v, node* u) { 233 | if (v == NULL) { 234 | return u; 235 | } 236 | if (u == NULL) { 237 | return v; 238 | } 239 | v = get_rightmost(v); 240 | assert(v->r == NULL); 241 | splay(u); 242 | v->push(); 243 | v->r = u; 244 | v->pull(); 245 | return v; 246 | } 247 | 248 | int count_left(node* v, const function &is_right) { 249 | if (v == NULL) { 250 | return 0; 251 | } 252 | pair p = find(v, [&](node* u) { return is_right(u) ? -1 : 1; }); 253 | node* u = p.first; 254 | return (u->l != NULL ? u->l->sz : 0) + (p.second == 1); 255 | } 256 | 257 | node* add(node* r, node* v, const function &go_left) { 258 | pair p = split(r, go_left); 259 | return merge(p.first, merge(v, p.second)); 260 | } 261 | 262 | node* remove(node* v) { // returns the new root 263 | splay(v); 264 | v->push(); 265 | node* x = v->l; 266 | node* y = v->r; 267 | v->l = v->r = NULL; 268 | node* z = merge(x, y); 269 | if (z != NULL) { 270 | z->p = v->p; 271 | } 272 | v->p = NULL; 273 | v->push(); 274 | v->pull(); // now v might be reusable... 275 | return z; 276 | } 277 | 278 | node* next(node* v) { 279 | splay(v); 280 | v->push(); 281 | if (v->r == NULL) { 282 | return NULL; 283 | } 284 | v = v->r; 285 | while (v->l != NULL) { 286 | v->push(); 287 | v = v->l; 288 | } 289 | splay(v); 290 | return v; 291 | } 292 | 293 | node* prev(node* v) { 294 | splay(v); 295 | v->push(); 296 | if (v->l == NULL) { 297 | return NULL; 298 | } 299 | v = v->l; 300 | while (v->r != NULL) { 301 | v->push(); 302 | v = v->r; 303 | } 304 | splay(v); 305 | return v; 306 | } 307 | 308 | int get_size(node* v) { 309 | splay(v); 310 | return (v != NULL ? v->sz : 0); 311 | } 312 | 313 | template 314 | void apply(node* v, T... args) { 315 | splay(v); 316 | v->unsafe_apply(args...); 317 | } 318 | 319 | void reverse(node* v) { 320 | splay(v); 321 | v->unsafe_reverse(); 322 | } 323 | } 324 | 325 | using namespace splay_tree; 326 | 327 | int main() { 328 | ios::sync_with_stdio(false); 329 | cin.tie(0); 330 | int n, m; 331 | cin >> n >> m; 332 | string s; 333 | cin >> s; 334 | map> mp; 335 | for (int i = 0; i < n; i++) { 336 | mp[s[i]].insert(i); 337 | } 338 | node* v = NULL; 339 | vector nodes(n); 340 | for (int i = 0; i < n; i++) { 341 | nodes[i] = new node(i); 342 | v = merge(v, nodes[i]); 343 | } 344 | while (m--) { 345 | int l, r; 346 | char c; 347 | cin >> l >> r >> c; 348 | l--; r--; 349 | l = get_kth(v, l)->id; 350 | r = get_kth(v, r)->id; 351 | while (true) { 352 | auto it = mp[c].lower_bound(l); 353 | if (it == mp[c].end() || *it > r) { 354 | break; 355 | } 356 | v = remove(nodes[*it]); 357 | mp[c].erase(it); 358 | } 359 | } 360 | v = get_leftmost(v); 361 | while (v != NULL) { 362 | cout << s[v->id]; 363 | v = next(v); 364 | } 365 | cout << '\n'; 366 | return 0; 367 | } -------------------------------------------------------------------------------- /cpp/Data Structures/treap.cpp: -------------------------------------------------------------------------------- 1 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 2 | 3 | struct node{ 4 | int prior=rng(), val, size=1; 5 | node *l=0, *r=0; 6 | node(int v) 7 | { 8 | val=v; 9 | } 10 | }; 11 | 12 | typedef node* pnode; 13 | 14 | #define sz(t) (t?t->size:0) 15 | 16 | void update(pnode t) 17 | { 18 | if(!t) return ; 19 | t->size = sz(t->l)+1+sz(t->r); 20 | } 21 | 22 | void split(pnode t,pnode &l,pnode &r, int key){ 23 | if(!t) l=r=0; 24 | else if(t->val<=key) split(t->r,t->r,r,key), l=t; 25 | else split(t->l,l,t->l,key), r=t; 26 | update(t); 27 | } 28 | 29 | void merge(pnode &t, pnode l, pnode r) 30 | { 31 | if(!l) t=r; 32 | else if(!r) t=l; 33 | else if(l->prior>r->prior) merge(l->r, l->r, r), t=l; 34 | else merge(r->l, l, r->l), t=r; 35 | update(t); 36 | } 37 | 38 | void disp(pnode root) 39 | { 40 | if(!root) return ; 41 | disp(root->l); 42 | cout<val<<" "; 43 | disp(root->r); 44 | return ; 45 | } 46 | 47 | void insert(pnode &t, pnode &x) //insert of implicit treap also works, but slower 48 | { 49 | if(!t) t=x; 50 | else if(x->prior > t->prior) split(t, x->l, x->r, x->val), t=x; 51 | else if(x->val<=t->val) insert(t->l, x); 52 | else insert(t->r, x); 53 | update(t); 54 | } 55 | 56 | void erase(pnode &t, int val) 57 | { 58 | if(!t) return ; 59 | if(val < t->val) erase(t->l, val); 60 | else if(val> t->val) erase(t->r, val); 61 | else {pnode tmp=t; merge(t, t->l, t->r); free(tmp);} 62 | update(t); 63 | } 64 | 65 | bool find(pnode &t, int val) 66 | { 67 | if(!t) return 0; 68 | if(valval) return find(t->l, val); 69 | if(val>t->val) return find(t->r, val); 70 | return 1; 71 | } 72 | 73 | int less_than(pnode t, ll x) //elem <=x 74 | { 75 | if(!t) return 0; 76 | if(t->vall)+1+less_than(t->r, x); 77 | if(t->val==x) return sz(t->l)+1; 78 | return less_than(t->l, x); 79 | } 80 | 81 | ll kth(pnode t, int k) //kth smallest 82 | { 83 | if(sz(t->l)+1==k) return t->val; 84 | if(k<=sz(t->l)) return kth(t->l, k); 85 | return kth(t->r, k-1-sz(t->l)); 86 | } 87 | 88 | // pnode root=0; -------------------------------------------------------------------------------- /cpp/Data Structures/trie without pointer.cpp: -------------------------------------------------------------------------------- 1 | struct node{ 2 | int f=0; 3 | int child[2]={}; 4 | }; 5 | 6 | node nil; 7 | 8 | vector trie(1, nil); 9 | 10 | inline void insert(int purana, int naya, int val) 11 | { 12 | for(int idx=30; idx>=0; --idx){ 13 | trie[naya].f=trie[purana].f+1; 14 | if((val>>idx)&1){ 15 | trie[naya].child[0]=trie[purana].child[0]; 16 | purana=trie[purana].child[1]; 17 | trie[naya].child[1]=trie.size(); 18 | trie.pb(nil); 19 | naya=trie.size()-1; 20 | continue; 21 | } 22 | trie[naya].child[1]=trie[purana].child[1]; 23 | purana=trie[purana].child[0]; 24 | trie[naya].child[0]=trie.size(); 25 | trie.pb(nil); 26 | naya=trie.size()-1; 27 | } 28 | trie[naya].f=trie[purana].f+1; 29 | return ; 30 | } 31 | 32 | int ans; 33 | 34 | inline void qry1(int l, int r, int val) 35 | { 36 | for(int idx=30; idx>=0; --idx){ 37 | if((val>>idx)&1){ 38 | //try to get 0 39 | if(trie[trie[r].child[0]].f - trie[trie[l].child[0]].f){ 40 | l=trie[l].child[0]; 41 | r=trie[r].child[0]; 42 | continue; 43 | } 44 | //make do with 1 45 | ans|=(1< 2 | inline void hash_combine(size_t &seed, const T &v) 3 | { 4 | std::hash hasher; 5 | seed^=hasher(v)+0x9e3779b9+(seed<<6)+(seed>>2); 6 | } 7 | 8 | namespace std 9 | { 10 | template struct hash> 11 | { 12 | inline size_t operator()(const pair & v) const 13 | { 14 | size_t seed = 0; 15 | ::hash_combine(seed, v.first); 16 | ::hash_combine(seed, v.second); 17 | return seed; 18 | } 19 | }; 20 | } 21 | 22 | //.reserve(1e6); 23 | //.max_load_factor(.25); 24 | 25 | // Attribution: https://codeforces.com/blog/entry/62393 26 | struct custom_hash { 27 | static uint64_t splitmix64(uint64_t x) { 28 | // http://xorshift.di.unimi.it/splitmix64.c 29 | x += 0x9e3779b97f4a7c15; 30 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 31 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 32 | return x ^ (x >> 31); 33 | } 34 | 35 | size_t operator()(uint64_t x) const { 36 | static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 37 | return splitmix64(x + FIXED_RANDOM); 38 | } 39 | }; 40 | 41 | typedef unordered_map safe_map; -------------------------------------------------------------------------------- /cpp/Dynamic Programming/convex hull dp set.cpp: -------------------------------------------------------------------------------- 1 | //Attribution - https://csacademy.com/submission/1375368/ 2 | const ll is_query = -(1LL<<62); 3 | struct Line { 4 | ll m, b; 5 | mutable function succ; 6 | bool operator<(const Line& rhs) const { 7 | if (rhs.b != is_query) return m < rhs.m; //change sign here 8 | const Line* s = succ(); 9 | if (!s) return 0; 10 | ll x = rhs.m; 11 | return b - s->b < (s->m - m) * x; //and here to get minimum 12 | } 13 | }; 14 | struct CHT : public multiset { // will maintain upper hull for maximum 15 | bool bad(iterator y) { 16 | auto z = next(y); 17 | if (y == begin()) { 18 | if (z == end()) return 0; 19 | return y->m == z->m && y->b <= z->b; 20 | } 21 | auto x = prev(y); 22 | if (z == end()) return y->m == x->m && y->b <= x->b; 23 | return double(x->b - y->b)*(z->m - y->m) >= double(y->b - z->b)*(y->m - x->m); 24 | } 25 | void insert_line(ll m, ll b) { 26 | auto y = insert({ m, b }); 27 | y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; 28 | if (bad(y)) { erase(y); return; } 29 | while (next(y) != end() && bad(next(y))) erase(next(y)); 30 | while (y != begin() && bad(prev(y))) erase(prev(y)); 31 | } 32 | ll eval(ll x) { 33 | auto l = *lower_bound((Line) { x, is_query }); 34 | return l.m * x + l.b; 35 | } 36 | }; -------------------------------------------------------------------------------- /cpp/Dynamic Programming/convex hull dp.cpp: -------------------------------------------------------------------------------- 1 | // mantains minimum hull 2 | struct CHT{ 3 | typedef pll line; 4 | double infy=1e40; 5 | 6 | vector hull; 7 | 8 | #define val(l, x) (l.ff*x+l.ss) 9 | 10 | double ovrtake(line l1, line l2) 11 | { 12 | if(l1.ff==l2.ff) 13 | if(l1.ss=2) 24 | if((n=hull.size()) && ovrtake(l, hull[n-2])<=ovrtake(hull[n-1], hull[n-2])) hull.ppb(); 25 | else break; 26 | hull.pb(l); 27 | } 28 | 29 | ll eval(ll x) 30 | { 31 | if(hull.empty()) return inf; // change to -inf and <= to >= below for max hull 32 | if(hull.size()==1) return val(hull[0], x); 33 | int n=hull.size(), en=hull.size()-1, st=0, mid; 34 | while(st<=en) 35 | if((mid=(st+en)/2)==0 || val(hull[mid], x)<=val(hull[mid-1], x)) 36 | if(mid+1==n || val(hull[mid], x)<=val(hull[mid+1], x)) return val(hull[mid], x); 37 | else st=mid+1; 38 | else en=mid-1; 39 | return 0; 40 | } 41 | }; -------------------------------------------------------------------------------- /cpp/Dynamic Programming/divide and conquer dp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | attribution: cp-algorithms.com 3 | necessary conditions: 4 | dp(i,j)= min k ≤ j {dp(i−1,k-1)+C(k,j)} 5 | opt(i,j) ≤ opt(i,j+1) 6 | */ 7 | 8 | bool act=0; //keep toggling active 9 | int C[N][N]; //define cost function/matrix, proof usually involves C 10 | int dp[2][N]; 11 | 12 | // compute dp[act][l] ... dp[act][r] 13 | inline void compute(int l, int r, int optl, int optr) 14 | { 15 | if(l > r) return; 16 | int mid = (l + r) >> 1, en = min(mid, optr), &best = dp[act][mid] = inf, cur, opt; 17 | 18 | for(int k = optl; k <= en; ++k) { 19 | cur = dp[!act][k-1] + C[k][mid]; 20 | if(cur < best) best = cur, opt = k; 21 | } 22 | 23 | compute(l, mid - 1, optl, opt); 24 | compute(mid + 1, r, opt, optr); 25 | } 26 | /* 27 | // 1 based indexing 28 | for(int groups=1; groups<=k; ++groups){ 29 | act^=1; 30 | compute(groups, n, groups, n); 31 | } 32 | */ -------------------------------------------------------------------------------- /cpp/Dynamic Programming/knuth optimization.cpp: -------------------------------------------------------------------------------- 1 | ll dp[m][m]; 2 | int r[m][m]; 3 | for(int j=0; j=0; i--){ 5 | dp[i][j]=INF; 6 | if(ji+2){ 14 | int lo=r[i][j-1]; 15 | int hi=r[i+1][j]; 16 | for(int k=lo; k<=hi; k++){ 17 | if(dp[i][k]+dp[k][j]+a[j]-a[i]=0; --mask){ 15 | if(mask&(1<0; i=(i-1)&mask) -------------------------------------------------------------------------------- /cpp/Game Theory/grundy.cpp: -------------------------------------------------------------------------------- 1 | int grundyPosition(int x , int y){ 2 | if(memo[x][y] != -1) return memo[x][y] ; 3 | sets ; s.clear() ; 4 | for(int i = 0 ; i < 3 ; i++){ 5 | if(valid(x+dx[i], y+dy[i])){ 6 | s.insert(grundyPosition(x+dx[i],y+dy[i])) ; 7 | } 8 | } 9 | int ret = 0; 10 | while(s.find(ret) != s.end()) ret++ ; 11 | return memo[x][y] = ret ; 12 | } -------------------------------------------------------------------------------- /cpp/Geometry/circle.cpp: -------------------------------------------------------------------------------- 1 | //attribution: https://www.hackerrank.com/rest/contests/master/challenges/weird-queries/hackers/ShikChen/download_solution?primary=true 2 | struct circle{ 3 | double abs2(pt a) { return a.x*a.x+a.y*a.y; } 4 | const double eps=1e-6; 5 | pt o; double r2; 6 | circle() { o.x=o.y=r2=0; } 7 | circle(pt a) { o=a; r2=0; } 8 | circle(pt a, pt b) { o=(a+b)/2; r2=dist2(o,a); } 9 | circle(pt a, pt b, pt c) { 10 | double i, j, k, A=2*cross(b-a, c-a)*cross(b-a, c-a); 11 | i=abs2(b-c)*dot(a-b, a-c); 12 | j=abs2(a-c)*dot(b-a, b-c); 13 | k=abs2(a-b)*dot(c-a, c-b); 14 | o.x=(i*a.x+j*b.x+k*c.x)/A; 15 | o.y=(i*a.y+j*b.y+k*c.y)/A; 16 | r2=dist2(o,a); 17 | } 18 | bool cover(pt a) { return dist2(o,a)<=r2+eps; } 19 | }; -------------------------------------------------------------------------------- /cpp/Geometry/closestPair.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define all(x) x.begin(),x.end() 3 | #define mp(x,y) make_pair(x,y) 4 | #define pb(x) push_back(x) 5 | #define pf(x) push_front(x) 6 | #define ppb(x) pop_back(x) 7 | #define ppf(x) pop_front(x) 8 | #define clr(a,b) memset(a,b,sizeof a) 9 | #define x first 10 | #define y second 11 | #define umap unordered_map 12 | #define fr(i,n) for(int i=0;i pii; 22 | typedef pair pli; 23 | typedef pair pil; 24 | typedef pair pll; 25 | typedef vector vi; 26 | typedef vector vl; 27 | typedef vector vc; 28 | typedef vector vll; 29 | typedef vector vb; 30 | typedef vector vd; 31 | 32 | /*primes*/ 33 | //ll p1=1e6+3, p2=1616161, p3=3959297, p4=7393931; 34 | //freopen("in.txt" , "r" , stdin) ; 35 | //freopen("out.txt" , "w" , stdout) ; 36 | 37 | typedef pair pt; 38 | 39 | vector Sx; 40 | 41 | struct compare_y{ 42 | bool operator()(const pt &p1, const pt &p2) 43 | { 44 | if(p1.y!=p2.y) return p1.y>n; 61 | Sx.resize(n); 62 | fr(i, n){ 63 | cin>>Sx[i].x>>Sx[i].y; 64 | } 65 | 66 | sort(all(Sx)); 67 | set Sy; 68 | double ans=inf; 69 | int tail=0; 70 | 71 | for(int i=0; i=ans){ 74 | Sy.erase(Sx[tail]); 75 | ++tail; 76 | } 77 | 78 | auto it1=Sy.lwr(mp(-inf, Sx[i].y-ans)); 79 | auto it2=Sy.lwr(mp(-inf, Sx[i].y+ans)); 80 | while(it1!=it2){ 81 | ans=min(ans, dist(*it1, Sx[i])); 82 | ++it1; 83 | } 84 | Sy.insert(Sx[i]); 85 | } 86 | 87 | cout< 0; 15 | } 16 | 17 | void convex_hull(vector& a) { 18 | if (a.size() == 1) 19 | return; 20 | 21 | sort(a.begin(), a.end(), &cmp); 22 | pt p1 = a[0], p2 = a.back(); 23 | vector up, down; 24 | up.push_back(p1); 25 | down.push_back(p1); 26 | for (int i = 1; i < (int)a.size(); i++) { 27 | if (i == a.size() - 1 || cw(p1, a[i], p2)) { 28 | while (up.size() >= 2 && !cw(up[up.size()-2], up[up.size()-1], a[i])) 29 | up.pop_back(); 30 | up.push_back(a[i]); 31 | } 32 | if (i == a.size() - 1 || ccw(p1, a[i], p2)) { 33 | while(down.size() >= 2 && !ccw(down[down.size()-2], down[down.size()-1], a[i])) 34 | down.pop_back(); 35 | down.push_back(a[i]); 36 | } 37 | } 38 | 39 | a.clear(); 40 | for (int i = 0; i < (int)up.size(); i++) 41 | a.push_back(up[i]); 42 | for (int i = down.size() - 2; i > 0; i--) 43 | a.push_back(down[i]); 44 | } -------------------------------------------------------------------------------- /cpp/Geometry/geoTemplate.cpp: -------------------------------------------------------------------------------- 1 | namespace geometry{ 2 | #define base double 3 | struct pt{ 4 | base x, y; 5 | }; 6 | 7 | const double pi=2.*acos(0); 8 | 9 | double toRadian(double dgre){ return (pi*dgre)/180;} 10 | double toDegree(double rad){ return (180*rad)/pi;} 11 | base dist2(pt p){ return p.x*p.x + p.y*p.y;} 12 | double dist(pt p){ return sqrtl(dist2(p));} 13 | pt operator-(pt p1, pt p2){return {p1.x-p2.x, p1.y-p2.y};} 14 | pt operator+(pt p1, pt p2){return {p1.x+p2.x, p1.y+p2.y};} 15 | pt operator*(pt p, base d){return {p.x*d, p.y*d};} 16 | pt operator*(base d, pt p){return {p.x*d, p.y*d};} 17 | pt operator/(pt p, base d){return {p.x/d, p.y/d};} 18 | pt operator/(base d, pt p){return {p.x/d, p.y/d};} 19 | pt perp(pt p){return {-p.y, p.x};} // rotates +90 degrees 20 | base cross(pt p1, pt p2){return p1.x*p2.y - p1.y*p2.x;} 21 | base dot(pt p1, pt p2){return p1.x*p2.x+p1.y*p2.y;} 22 | pt rotl(pt p){return {-p.y, p.x};} 23 | pt rotr(pt p){return {p.y, -p.x};} 24 | //rotate p ’ang ’ radians ccw around origin 25 | pt rotate(pt p, double ang){return {p.x*cos(ang)-p.y*sin(ang), p.x*sin(ang)+p.y*cos(ang)};} 26 | pt unit(pt p){return p/dist(p);} 27 | pt normal(pt p){return unit(perp(p));} 28 | 29 | bool isParallel(pt a, pt b, pt c, pt d) 30 | { 31 | return cross(b-a, d-c)==0; 32 | } 33 | 34 | bool isColinear(pt a, pt b, pt c) 35 | { 36 | return cross(a-b, a-c)==0; 37 | } 38 | 39 | bool isColinear(pt a, pt b, pt c, pt d) 40 | { 41 | return isColinear(a, b, c) && isColinear(b, c, d); 42 | } 43 | 44 | bool isLeft(pt front, pt back, pt p) 45 | { 46 | return cross(front-back, p-back)>0; 47 | } 48 | 49 | bool oppositeSides(pt a, pt b, pt c, pt d) 50 | { 51 | return isLeft(a, b, c)!=isLeft(a, b, d); 52 | } 53 | 54 | bool isBetween(pt a, pt b, pt c) 55 | { 56 | if(!isColinear(a, b, c)) return 0; 57 | return min(a.x, b.x)<=c.x && c.x<=max(a.x, b.x) && min(a.y, b.y)<=c.y && c.y<=max(a.y,b.y); 58 | } 59 | 60 | /* 61 | 1:intersects at 1 pt 62 | 0:doesn't intersect 63 | -1:intersects at oo points 64 | */ 65 | int lineIntersection(pt a, pt b, pt c, pt d, pt &res) 66 | { 67 | if(cross(b-a, d-c)){ 68 | res=c-(d-c)*cross(b-a, c-a)/cross(b-a, d-c); 69 | return 1; 70 | } 71 | return -isColinear(a, b, c, d); 72 | } 73 | 74 | double lineDist(pt a, pt b, pt p){ 75 | return abs(cross(b-a, p-a)/dist(b-a)); 76 | } 77 | 78 | bool segmentIntersect(pt a, pt b, pt c, pt d) 79 | { 80 | if(isBetween(a, b, c) || isBetween(a, b, d) || 81 | isBetween(c, d, a) || isBetween(c, d, b)) return 1; 82 | return oppositeSides(a, b, c, d) && oppositeSides(c, d, a, b); 83 | } 84 | 85 | double segmentDistance(pt v, pt w, pt p) 86 | { 87 | double l2 = dist2(v-w); 88 | if (l2 == 0.0) return dist(p-v); 89 | double t = max(double(0), min(double(1), dot(p - v, w - v) / l2)); 90 | pt projection = v + t * (w - v); 91 | return dist2(p-projection); 92 | } 93 | } 94 | 95 | using namespace geometry; 96 | 97 | 98 | 99 | bool inTriangle(pt a, pt b, pt c, pt d) 100 | { 101 | if(isBetween(a, b, d) || isBetween(a, c, d) || isBetween(b, c, d)) return 0; //change to allow pts on perimeter 102 | return isLeft(a, b, d)==isLeft(b, c, d) && isLeft(c, a, d)==isLeft(b, c, d); 103 | } 104 | 105 | bool isConvex(vector &vertices) 106 | { 107 | int n = vertices.size(); 108 | bool first=isLeft(vertices[0], vertices[1], vertices[3]); 109 | for(size_t i=1; i &vertices) 115 | { 116 | double ans=0; 117 | for(int i=1; i+1=R.y) return true; 73 | else return false; 74 | } 75 | else{ 76 | if(min(P.x, Q.x)<=R.x && max(P.x, Q.x)>=R.x) return true; 77 | else return false; 78 | } 79 | } 80 | 81 | bool isParallel(line l1, line l2) 82 | { 83 | return l1.a*l2.b-l2.a*l1.b==0; 84 | } 85 | 86 | point line2lineIntersect(line l1, line l2) 87 | { 88 | double det=l1.a*l2.b-l2.a*l1.b; 89 | return point( (l2.b*l1.c-l1.b*l2.c)/det, (l1.a*l2.c-l2.a*l1.c)/det ); 90 | } 91 | 92 | bool lies(point P, point Q, point R){ //lies on line segment 93 | if( (Q - P)*(R - P) != vktr(0, 0, 0) ) return false; 94 | else return liescollinear(P, Q, R); 95 | } 96 | 97 | double distPointLine(line l1, point p){ return norm((l1.p2-l1.p1)*(p-l1.p1))/norm(l1.p2-l1.p1); } 98 | 99 | 100 | vktr rotateCWx(vktr v, double theta) //around x axis 101 | { return vktr(v.x, v.y*cos(theta)-v.z*sin(theta), v.y*sin(theta)+v.z*cos(theta)); } 102 | 103 | vktr rotateCWy(vktr v, double theta) //around y axis 104 | { return vktr(v.z*sin(theta)+v.x*cos(theta), v.y, v.z*cos(theta)-v.x*sin(theta)); } 105 | 106 | vktr rotateCWz(vktr v, double theta) //around z axis 107 | { return vktr(v.x*cos(theta)-v.y*sin(theta), v.x*sin(theta)+v.y*cos(theta), v.z); } 108 | 109 | double cross2D(vktr v1, vktr v2) //value retuned is only z component as x & y=0 in cross prod 110 | { return v1.x*v2.y - v1.y*v2.x; } 111 | 112 | bool isCW(point p1, point p2, point p3) //2D 113 | { return cross2D(p1-p2, p3-p2)>0; } 114 | 115 | bool coolinear(point p1, point p2, point p3) 116 | { return cross2D(p1-p2, p3-p2)==0; } 117 | 118 | bool isConvex(const vector &vertices) 119 | { 120 | int n=vertices.size(); 121 | bool first=isCW(vertices[0], vertices[1], vertices[3]); 122 | for(int i=1; i &vertices) 129 | { 130 | int n=vertices.size(); 131 | double ans=0; 132 | for(int i=1; i+1comp[i|1]); 62 | 63 | return 1; 64 | } 65 | } -------------------------------------------------------------------------------- /cpp/Graph/articulation_points.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | N: Number of Vertices 3 | M: Number of Edges 4 | adj should contain neighbours of the form: {Vertex no., Edge no.} 5 | After running dfs(1), isArt[i] will be one if Vertex number 'i' is an articulation point 6 | NOTE: 7 | always ctr>=1 since disc relies on it being 0 only for undiscovered vertices 8 | */ 9 | 10 | int disc[N], low[N], parent[N], child[N]; 11 | bool isArt[M]; 12 | vector> adj[N]; 13 | int ctr = 1; 14 | 15 | void dfs(int cur) 16 | { 17 | disc[cur] = low[cur] = ctr++; 18 | child[cur] = 0; 19 | 20 | for(auto i : adj[cur]) { 21 | if (i.first == parent[cur]) 22 | continue; 23 | if (disc[i.first]) { 24 | low[cur] = min(low[cur], disc[i.first]); 25 | continue; 26 | } 27 | child[cur]++; 28 | parent[i.first] = cur; 29 | dfs(i.first); 30 | low[cur] = min(low[cur], low[i.first]); 31 | if (parent[cur] && low[i.ff] >= low[cur]) { 32 | isArt[cur] = 1; 33 | } 34 | } 35 | if (!parent[cur] && child[cur] > 1) { 36 | isArt[cur] = 1; 37 | } 38 | } -------------------------------------------------------------------------------- /cpp/Graph/bridges.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | N: Number of Vertices 3 | M: Number of Edges 4 | adj should contain neighbours of the form: {Vertex no., Edge no.} 5 | After running dfs(1), isBridge[i] will be one if Edge number 'i' is a bridge 6 | NOTE: 7 | always ctr>=1 since disc relies on it being 0 only for undiscovered vertices 8 | */ 9 | 10 | int disc[N], low[N], parent[N]; 11 | bool isBridge[M]; 12 | vector> adj[N]; 13 | 14 | void dfs(int cur) 15 | { 16 | disc[cur] = low[cur] = ctr++; 17 | 18 | for(auto i : adj[cur]) { 19 | if (i.first == parent[cur]) 20 | continue; 21 | if (disc[i.first]) { 22 | low[cur] = min(low[cur], disc[i.first]); 23 | continue; 24 | } 25 | parent[i.first] = cur; 26 | dfs(i.first); 27 | if (low[i.first] <= low[cur]) { 28 | low[cur] = low[i.first]; 29 | } else if(low[i.first] > disc[cur]) { 30 | isBridge[i.second]=1; 31 | } 32 | } 33 | } 34 | 35 | vector component; 36 | vector> nadj; 37 | 38 | void dfs1(int cur) 39 | { 40 | component[cur] = ctr; 41 | for (auto i : adj[cur]) { 42 | if (isBridge[i.second] || component[i.first]) 43 | continue; 44 | dfs1(i.first); 45 | } 46 | } 47 | 48 | void makeBridgeTree(int n) 49 | { 50 | ctr = 0; 51 | component.assign(n + 1, 0); 52 | for (int i = 1; i <= n; ++i) { 53 | if (component[i]) 54 | continue; 55 | ++ctr; 56 | dfs1(i); 57 | } 58 | 59 | nadj.assign(ctr + 1, vector()); 60 | 61 | for (int i = 1; i <= n; ++i) { 62 | int &ci = component[i]; 63 | for (auto j : adj[i]) { 64 | int &cj = component[j.first]; 65 | if (ci == cj) 66 | continue; 67 | nadj[ci].push_back(cj); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /cpp/Graph/centroid decomposition.cpp: -------------------------------------------------------------------------------- 1 | bool blocked[N] = {}; 2 | int subtree[N], maxtree[N]; 3 | vi comp; 4 | 5 | inline void solveTree(int cen) 6 | { 7 | 8 | } 9 | 10 | inline void calSub(int cur, int p) 11 | { 12 | subtree[cur] = 1; 13 | maxtree[cur] = 0; 14 | for (auto i : adj[cur]) { 15 | if (i == p || blocked[i]) continue; 16 | calSub(i, cur); 17 | subtree[cur] += subtree[i]; 18 | maxtree[cur] = max(maxtree[cur], subtree[i]); 19 | } 20 | comp.pb(cur); 21 | } 22 | 23 | inline void go(int entry) 24 | { 25 | comp.clear(); 26 | calSub(entry, -1); 27 | int cen = entry, n1 = comp.size(); 28 | for (auto i : comp) { 29 | maxtree[i] = max(maxtree[i], n1 - subtree[i]); 30 | if (maxtree[i] < maxtree[cen]) cen = i; 31 | } 32 | 33 | // trace(cen); 34 | 35 | solveTree(cen); 36 | blocked[cen] = 1; 37 | 38 | for (auto i : adj[cen]) { 39 | if (!blocked[i]) go(i); 40 | } 41 | } 42 | 43 | // go(1) -------------------------------------------------------------------------------- /cpp/Graph/centroid tree.cpp: -------------------------------------------------------------------------------- 1 | // attribution: https://codeforces.com/contest/342/submission/90467624 2 | 3 | struct CentroidDecomposition 4 | { 5 | const vector>& E; 6 | vector par, subsz, level, vis; 7 | vector> dist; 8 | 9 | int dfs(int u, int p, int h) 10 | { 11 | if (h != -1) dist[u][h] = dist[p][h] + 1; 12 | subsz[u] = 1; 13 | for (auto v : E[u]) 14 | if (not vis[v] && v != p) subsz[u] += dfs(v, u, h); 15 | return subsz[u]; 16 | } 17 | 18 | int find_centroid(int u, int p, int sz) 19 | { 20 | for (auto v : E[u]) 21 | if (not vis[v] && v != p && subsz[v] > sz / 2) 22 | return find_centroid(v, u, sz); 23 | return u; 24 | } 25 | 26 | void build(int u, int p) 27 | { 28 | int sz = dfs(u, p, p == -1 ? -1 : level[p]); 29 | int centroid = find_centroid(u, p, sz); 30 | par[centroid] = p, vis[centroid] = 1; 31 | if (p != -1) level[centroid] = level[p] + 1; 32 | for (auto v : E[centroid]) 33 | if (not vis[v]) build(v, centroid); 34 | } 35 | 36 | CentroidDecomposition(const vector>& E) : E(E) 37 | { 38 | int n = sz(E); 39 | par.assign(n, -1), subsz.assign(n, 0), vis.assign(n, 0); 40 | level.assign(n, 0), dist.assign(n, vector(31 - __builtin_clz(n), 0)); 41 | build(0, -1); 42 | } 43 | 44 | int lca(int u, int v) // centroid lca, not tree lca 45 | { 46 | if (level[u] < level[v]) swap(u, v); 47 | while (level[u] > level[v]) u = par[u]; 48 | while (u != v) u = par[u], v = par[v]; 49 | return u; 50 | } 51 | 52 | int distance(int u, int v) 53 | { 54 | int w = lca(u, v); 55 | return dist[u][level[w]] + dist[v][level[w]]; 56 | } 57 | }; -------------------------------------------------------------------------------- /cpp/Graph/diameterUnweighed.cpp: -------------------------------------------------------------------------------- 1 | int findDiameter(int n, int &a, int &b) 2 | { 3 | auto bfs = [&](int src, vi &dist) { 4 | queue q; 5 | int cur = 1; 6 | q.push(src); 7 | dist[src] = 0; 8 | 9 | while (!q.empty()) { 10 | src = q.front(); 11 | q.pop(); 12 | for (auto i : adj[src]) { 13 | if (dist[i] != -1) continue; 14 | q.push(i); 15 | dist[i] = dist[src] + 1; 16 | } 17 | } 18 | return src; 19 | }; 20 | 21 | vector dist(n + 1, -1); 22 | a = bfs(1, dist); 23 | fill(all(dist), -1); 24 | b = bfs(a, dist); 25 | return dist[b]; 26 | } 27 | -------------------------------------------------------------------------------- /cpp/Graph/dinic-maxflow.cpp: -------------------------------------------------------------------------------- 1 | // attribution: https://codeforces.com/contest/1423/submission/94770479 2 | // Dinic's algorithm for max flow 3 | // O(V^2 E) in general 4 | // O(min(V^{2/3}, E^1/2) E) in graphs with unit capacities 5 | // O(sqrt{V} E) in unit networks (e.g. bipartite matching) 6 | class Dinic { 7 | private: 8 | const static ll INF = 8*(ll)1e18; 9 | struct Edge { 10 | const int t; // Endpoint 11 | ll a; // Admissible flow 12 | Edge(int tar, ll cap = INF) : t(tar), a(cap) {} 13 | }; 14 | 15 | vector edges; 16 | vector> conns; 17 | vector dist, act_ind; 18 | 19 | ll push(int ei, ll v) { 20 | edges[ei].a -= v; 21 | edges[ei ^ 1].a += v; 22 | return v; 23 | } 24 | void calcDists(int sink) { 25 | for (int& v : dist) v = -1; 26 | dist[sink] = 0; 27 | vector que = {sink}; 28 | for (int j = 0; j < que.size(); ++j) { 29 | for (auto ei : conns[que[j]]) { 30 | int t = edges[ei].t; 31 | if (edges[ei^1].a > 0 && dist[t] == -1) { 32 | dist[t] = dist[que[j]] + 1; 33 | que.push_back(t); 34 | } 35 | } 36 | } 37 | } 38 | ll dfsFlow(int i, int sink, ll cap) { 39 | if (i == sink) return 0; 40 | for (int& j = act_ind[i]; j < conns[i].size(); ++j) { 41 | int ei = conns[i][j]; 42 | int t = edges[ei].t; 43 | if (dist[t] != dist[i] - 1 || edges[ei].a == 0) continue; 44 | 45 | ll subcap = min(cap, edges[ei].a); 46 | cap -= push(ei, subcap - dfsFlow(t, sink, subcap)); 47 | if (! cap) return 0; 48 | } 49 | return cap; 50 | } 51 | public: 52 | Dinic(int n) : conns(n), dist(n), act_ind(n) {} 53 | 54 | int addEdge(int s, int t, ll c = INF, bool dir = 1) { 55 | int i = edges.size() / 2; 56 | edges.emplace_back(t, c); 57 | edges.emplace_back(s, dir ? 0 : c); 58 | conns[s].push_back(2*i); 59 | conns[t].push_back(2*i+1); 60 | return i; 61 | } 62 | ll pushFlow(int source, int sink) { 63 | for (ll res = 0;;) { 64 | calcDists(sink); 65 | if (dist[source] == -1) return res; 66 | for (int& v : act_ind) v = 0; 67 | res += INF - dfsFlow(source, sink, INF); 68 | } 69 | } 70 | // Returns a min-cut containing the sink 71 | vector minCut() { 72 | vector res; 73 | for (int i = 0; i < dist.size(); ++i) { 74 | if (dist[i] == -1) res.push_back(i); 75 | } 76 | return res; 77 | } 78 | // Gives flow on edge assuming it is directed/undirected. Undirected flow is signed. 79 | ll getDirFlow(int i) const { return edges[2*i+1].a; } 80 | ll getUndirFlow(int i) const { return (edges[2*i+1].a - edges[2*i].a) / 2; 81 | } 82 | }; -------------------------------------------------------------------------------- /cpp/Graph/dsu_for_bipartiteness.cpp: -------------------------------------------------------------------------------- 1 | struct DSU{ 2 | int n, components; 3 | bool bipartite; 4 | vi par, sz; 5 | vector toggle; 6 | 7 | DSU(int _n) 8 | { 9 | n=components=_n; 10 | sz.assign(n+1, 1); 11 | par.resize(n+1); 12 | iota(all(par), 0); 13 | bipartite = true; 14 | toggle.assign(n + 1, false); 15 | } 16 | 17 | pair root(int x) 18 | { 19 | bool tog = toggle[x]; 20 | while (x != par[x]) { 21 | x = par[x]; 22 | tog ^= toggle[x]; 23 | } 24 | return {x, tog}; 25 | } 26 | 27 | bool merge(int a, int b) 28 | { 29 | if (!bipartite) 30 | return false; 31 | pii res1 = root(a), res2 = root(b); 32 | int x1 = res1.ff, x2 = res2.ff; 33 | bool ca = res1.ss, cb = res2.ss; 34 | if(x1 == x2) { 35 | if (ca == cb) { 36 | bipartite = false; 37 | } 38 | return false; 39 | } 40 | if(sz[x2]>sz[x1]) 41 | swap(x1, x2); 42 | par[x2]=x1; sz[x1]+=sz[x2]; 43 | toggle[x2] = toggle[x2] ^ (ca == cb); 44 | --components; 45 | return true; 46 | } 47 | }; -------------------------------------------------------------------------------- /cpp/Graph/edmonds karp(ford fulkerson).cpp: -------------------------------------------------------------------------------- 1 | const int N=2e3+1; 2 | int inf=1e9; 3 | 4 | int cap[N][N]; 5 | vector par, adj[N]; 6 | 7 | void add_edge(int a, int b, int c) 8 | { 9 | cap[a][b]+=c; 10 | adj[a].pb(b); 11 | adj[b].pb(a); 12 | } 13 | 14 | int bfs(int s, int t) 15 | { 16 | fill(all(par), -1); 17 | par[s]=-2; 18 | queue> q; 19 | q.push({s, inf}); 20 | pair top; 21 | int nf; 22 | while(!q.empty()){ 23 | top=q.front(); 24 | q.pop(); 25 | for(auto i:adj[top.first]){ 26 | nf=min(top.second, cap[top.first][i]); 27 | if(!nf || par[i]!=-1) continue; 28 | par[i]=top.first; 29 | if(i==t) return nf; 30 | q.push({i, nf}); 31 | } 32 | } 33 | return 0; 34 | } 35 | 36 | int maxflow(int s, int t) 37 | { 38 | int ans=0, flow, cur; 39 | while((flow=bfs(s, t))){ 40 | ans+=flow; 41 | cur=t; 42 | while(cur!=s){ 43 | cap[par[cur]][cur]-=flow; 44 | cap[cur][par[cur]]+=flow; 45 | cur=par[cur]; 46 | } 47 | } 48 | return ans; 49 | } 50 | 51 | // par.resize(nodes+1); -------------------------------------------------------------------------------- /cpp/Graph/euler_path_and_cycle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Finds Euler Path / Cycle in O(M + N) 3 | Remember to call reset before finding answer 4 | Path will be present in ans 5 | ans will contain the edge ids of the path 6 | */ 7 | 8 | int n, m; 9 | 10 | vector> edges; 11 | vector used; 12 | vector ans, pos; 13 | vector adj[N]; 14 | 15 | void reset() 16 | { 17 | ans.clear(); 18 | pos.assign(n + 1, 0); 19 | used.assign(m, 0); 20 | } 21 | 22 | // returns other side of edge 23 | int getOther(int id, int v) 24 | { 25 | return edges[id].first ^ edges[id].second ^ v; 26 | } 27 | 28 | // finds euler path/cycle ending at v 29 | // for cycle check that oddCount in checkEuler is 0 30 | void dfs(int v) 31 | { 32 | // need to keep pos array since we might 33 | // visit v again, wouldn't want to start over 34 | while(pos[v] < (int)adj[v].size()) { 35 | int id = adj[v][pos[v]]; 36 | pos[v]++; 37 | if (used[id]) continue; 38 | used[id] = 1; 39 | dfs(getOther(id, v)); 40 | ans.pb(id); 41 | } 42 | } 43 | 44 | vector getVertices(int ending, vector edges) 45 | { 46 | vector path; 47 | reverse(all(edges)); 48 | int cur = ending; 49 | ans.pb(cur); 50 | 51 | for (auto i : edges) { 52 | cur = getOther(i, cur); 53 | path.pb(cur); 54 | } 55 | 56 | reverse(all(path)); 57 | return path; 58 | } 59 | 60 | void checkEuler(int src) 61 | { 62 | int oddCount = 0; 63 | for (int i = 1; i <= n; ++i) { 64 | bool parity = 0; 65 | for (auto j : adj[i]) { 66 | parity ^= !used[j]; 67 | } 68 | if (parity && i != src) ++oddCount; 69 | } 70 | 71 | if (oddCount > 1) return ; 72 | // oddCount of 1 => src is definately odd parity 73 | // since sum of degrees of all vertices is even = 2 * |E| 74 | // oddCount 0 => Euler Cycle 75 | dfs(src); 76 | } -------------------------------------------------------------------------------- /cpp/Graph/heavy_light_decomposition.cpp: -------------------------------------------------------------------------------- 1 | Segtree st; 2 | 3 | // taken from cp-algorithms.com 4 | vector parent, depth, heavy, head, pos, path; 5 | int cur_pos; 6 | vector adj[N]; 7 | int n; 8 | 9 | int dfs(int v) { 10 | int size = 1; 11 | int max_c_size = 0; 12 | for (int c : adj[v]) { 13 | if (c == parent[v]) 14 | continue; 15 | parent[c] = v; 16 | depth[c] = depth[v] + 1; 17 | int c_size = dfs(c); 18 | size += c_size; 19 | if (c_size > max_c_size) 20 | max_c_size = c_size, heavy[v] = c; 21 | } 22 | return size; 23 | } 24 | 25 | void decompose(int v, int h) { 26 | head[v] = h; 27 | path.push_back(v); 28 | pos[v] = cur_pos++; 29 | if (heavy[v] != -1) 30 | decompose(heavy[v], h); 31 | for (int c : adj[v]) 32 | if (c == parent[v] || c == heavy[v]) 33 | continue; 34 | else 35 | decompose(c, c); 36 | } 37 | 38 | 39 | 40 | void init() { 41 | parent.resize(n + 1); 42 | depth.resize(n + 1); 43 | heavy.resize(n + 1, -1); 44 | head.resize(n + 1); 45 | pos.resize(n + 1); 46 | cur_pos = 0; 47 | 48 | dfs(1); 49 | decompose(1, 0); 50 | } 51 | 52 | // check return type for overflow 53 | int query(int a, int b) { 54 | int res = 0; 55 | for (; head[a] != head[b]; b = parent[head[b]]) { 56 | if (depth[head[a]] > depth[head[b]]) 57 | swap(a, b); 58 | int cur_heavy_path_max = st.query(pos[head[b]], pos[b]); 59 | res = max(res, cur_heavy_path_max); 60 | } 61 | if (depth[a] > depth[b]) swap(a, b); 62 | int last_heavy_path_max = st.query(pos[a], pos[b]); 63 | res = max(res, last_heavy_path_max); 64 | return res; 65 | } 66 | 67 | void update(int a, int b) { 68 | for (; head[a] != head[b]; b = parent[head[b]]) { 69 | if (depth[head[a]] > depth[head[b]]) swap(a, b); 70 | st.update(pos[head[b]], pos[b]); 71 | } 72 | if (depth[a] > depth[b]) swap(a, b); 73 | st.update(pos[a], pos[b]); 74 | } -------------------------------------------------------------------------------- /cpp/Graph/lca.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Expects vertices to be numbered [1, n] 3 | Expects adj list of correct size to be present globally 4 | */ 5 | 6 | const int level = 18; 7 | 8 | int par[level][N] = {}; 9 | vector depth; 10 | 11 | void precom(int n) 12 | { 13 | assert((1 << level) >= n); 14 | depth.assign(n + 1, 0); 15 | depth[1] = 0; 16 | queue q; 17 | q.push(1); 18 | 19 | auto populate = [&](int cur, int p) { 20 | par[0][cur] = p; 21 | depth[cur] = depth[p] + 1; 22 | int prevParent = p; 23 | 24 | for (int j = 1; j < level && prevParent; ++j) 25 | prevParent = par[j][cur] = par[j - 1][prevParent]; 26 | }; 27 | 28 | while (!q.empty()) { 29 | int cur = q.front(); 30 | q.pop(); 31 | for (auto i : adj[cur]) { 32 | if (i == par[0][cur]) continue; 33 | populate(i, cur); 34 | q.push(i); 35 | } 36 | } 37 | } 38 | 39 | int lca(int u, int v) 40 | { 41 | if (depth[v] < depth[u]) swap(u, v); 42 | int diff = depth[v] - depth[u]; 43 | 44 | for (int i = 0; i < level; i++) 45 | if ((1 << i) & diff) v = par[i][v]; 46 | 47 | if (u == v) return u; 48 | 49 | for (int i = level - 1; i >= 0; --i) 50 | if (par[i][u] != par[i][v]) { 51 | u = par[i][u]; 52 | v = par[i][v]; 53 | } 54 | return par[0][u]; 55 | } -------------------------------------------------------------------------------- /cpp/Graph/maximum bipartitie matching.cpp: -------------------------------------------------------------------------------- 1 | int n, m; 2 | const int N=1e5+1; 3 | 4 | vi a, b; 5 | vi adj[N]; 6 | umap seen; 7 | 8 | void init() 9 | { 10 | a.assign(n, -1); 11 | b.assign(m+1, -1); 12 | } 13 | 14 | bool match(int idx) 15 | { 16 | for(auto i:adj[idx]){ 17 | if(seen[i] || i==a[idx]) continue; 18 | seen[i]=1; 19 | if(b[i]==-1){ 20 | b[i]=idx; 21 | a[idx]=i; 22 | return 1; 23 | } 24 | if(match(b[i])){ 25 | b[i]=idx; 26 | a[idx]=i; 27 | return 1; 28 | } 29 | } 30 | return 0; 31 | } 32 | 33 | int main() 34 | { 35 | ios_base::sync_with_stdio(false); 36 | cin>>n>>m; 37 | init(); 38 | int x; 39 | int ans=0; 40 | fr(i, n){ 41 | cin>>x; 42 | for(int j=1; j*j<=x && j<=m; ++j){ 43 | if(x%j) continue; 44 | adj[i].pb(j); 45 | if(x/j<=m) adj[i].pb(x/j); 46 | } 47 | if(x<=m) adj[i].pb(x); 48 | seen.clear(); 49 | ans+=match(i); 50 | } 51 | cout< prio, curflow, prevedge, prevnode, q, pot; 15 | vector inqueue; 16 | vector > graph; 17 | MinCostMaxFlow() {} 18 | 19 | MinCostMaxFlow(int n): nodes(n), prio(n, 0), curflow(n, 0), 20 | prevedge(n, 0), prevnode(n, 0), q(n, 0), pot(n, 0), inqueue(n, 0), graph(n) {} 21 | 22 | void addEdge(int source, int to, int capacity, int cost) 23 | { 24 | edge a = {to, 0, capacity, cost, (int)graph[to].size()}; 25 | edge b = {source, 0, 0, -cost, (int)graph[source].size()}; 26 | graph[source].push_back(a); 27 | graph[to].push_back(b); 28 | } 29 | 30 | void bellman_ford(int source, vector &dist) 31 | { 32 | fill(dist.begin(), dist.end(), INT_MAX); 33 | dist[source] = 0; 34 | int qt=0; 35 | q[qt++] = source; 36 | for(int qh=0;(qh-qt)%nodes!=0;qh++) 37 | { 38 | int u = q[qh%nodes]; 39 | inqueue[u] = false; 40 | for(auto &e : graph[u]) 41 | { 42 | if(e.flow >= e.cap) 43 | continue; 44 | int v = e.to; 45 | int newDist = dist[u] + e.cost; 46 | if(dist[v] > newDist) 47 | { 48 | dist[v] = newDist; 49 | if(!inqueue[v]) 50 | { 51 | inqueue[v] = true; 52 | q[qt++ % nodes] = v; 53 | } 54 | } 55 | } 56 | } 57 | } 58 | 59 | pair minCostFlow(int source, int dest, int maxflow) 60 | { 61 | bellman_ford(source, pot); 62 | int flow = 0; 63 | int flow_cost = 0; 64 | while(flow < maxflow) 65 | { 66 | priority_queue, vector >, greater > > q; 67 | q.push({0, source}); 68 | fill(prio.begin(), prio.end(), INT_MAX); 69 | prio[source] = 0; 70 | curflow[source] = INT_MAX; 71 | while(!q.empty()) 72 | { 73 | int d = q.top().first; 74 | int u = q.top().second; 75 | q.pop(); 76 | if(d != prio[u]) 77 | continue; 78 | for(int i=0;i= e.cap) 83 | continue; 84 | int newPrio = prio[u] + e.cost + pot[u] - pot[v]; 85 | if(prio[v] > newPrio) 86 | { 87 | prio[v] = newPrio; 88 | q.push({newPrio, v}); 89 | prevnode[v] = u; 90 | prevedge[v] = i; 91 | curflow[v] = min(curflow[u], e.cap - e.flow); 92 | } 93 | } 94 | } 95 | if(prio[dest] == INT_MAX) 96 | break; 97 | for(int i=0;i> adj, cost, capacity; 9 | 10 | const int INF = 1e9; 11 | 12 | void shortest_paths(int n, int v0, vector& d, vector& p) { 13 | d.assign(n, INF); 14 | d[v0] = 0; 15 | vector m(n, 2); 16 | deque q; 17 | q.push_back(v0); 18 | p.assign(n, -1); 19 | 20 | while (!q.empty()) { 21 | int u = q.front(); 22 | q.pop_front(); 23 | m[u] = 0; 24 | for (int v : adj[u]) { 25 | if (capacity[u][v] > 0 && d[v] > d[u] + cost[u][v]) { 26 | d[v] = d[u] + cost[u][v]; 27 | p[v] = u; 28 | if (m[v] == 2) { 29 | m[v] = 1; 30 | q.push_back(v); 31 | } else if (m[v] == 0) { 32 | m[v] = 1; 33 | q.push_front(v); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | int min_cost_flow(int N, vector edges, int K, int s, int t) { 41 | adj.assign(N, vector()); 42 | cost.assign(N, vector(N, 0)); 43 | capacity.assign(N, vector(N, 0)); 44 | for (Edge e : edges) { 45 | adj[e.from].push_back(e.to); 46 | adj[e.to].push_back(e.from); 47 | cost[e.from][e.to] = e.cost; 48 | cost[e.to][e.from] = -e.cost; 49 | capacity[e.from][e.to] = e.capacity; 50 | } 51 | 52 | int flow = 0; 53 | int cost = 0; 54 | vector d, p; 55 | while (flow < K) { 56 | shortest_paths(N, s, d, p); 57 | if (d[t] == INF) 58 | break; 59 | 60 | // find max flow on that path 61 | int f = K - flow; 62 | int cur = t; 63 | while (cur != s) { 64 | f = min(f, capacity[p[cur]][cur]); 65 | cur = p[cur]; 66 | } 67 | 68 | // apply flow 69 | flow += f; 70 | cost += f * d[t]; 71 | cur = t; 72 | while (cur != s) { 73 | capacity[p[cur]][cur] -= f; 74 | capacity[cur][p[cur]] += f; 75 | cur = p[cur]; 76 | } 77 | } 78 | 79 | if (flow < K) 80 | return -1; 81 | else 82 | return cost; 83 | } -------------------------------------------------------------------------------- /cpp/Graph/push-relable.cpp: -------------------------------------------------------------------------------- 1 | const int inf = 1000000000; 2 | 3 | int n; 4 | vector> capacity, flow; 5 | vector height, excess; 6 | 7 | void push(int u, int v) 8 | { 9 | int d = min(excess[u], capacity[u][v] - flow[u][v]); 10 | flow[u][v] += d; 11 | flow[v][u] -= d; 12 | excess[u] -= d; 13 | excess[v] += d; 14 | } 15 | 16 | void relabel(int u) 17 | { 18 | int d = inf; 19 | for (int i = 0; i < n; i++) { 20 | if (capacity[u][i] - flow[u][i] > 0) 21 | d = min(d, height[i]); 22 | } 23 | if (d < inf) 24 | height[u] = d + 1; 25 | } 26 | 27 | vector find_max_height_vertices(int s, int t) { 28 | vector max_height; 29 | for (int i = 0; i < n; i++) { 30 | if (i != s && i != t && excess[i] > 0) { 31 | if (!max_height.empty() && height[i] > height[max_height[0]]) 32 | max_height.clear(); 33 | if (max_height.empty() || height[i] == height[max_height[0]]) 34 | max_height.push_back(i); 35 | } 36 | } 37 | return max_height; 38 | } 39 | 40 | int max_flow(int s, int t) 41 | { 42 | height.assign(n, 0); 43 | height[s] = n; 44 | flow.assign(n, vector(n, 0)); 45 | excess.assign(n, 0); 46 | excess[s] = inf; 47 | for (int i = 0; i < n; i++) { 48 | if (i != s) 49 | push(s, i); 50 | } 51 | 52 | vector current; 53 | while (!(current = find_max_height_vertices(s, t)).empty()) { 54 | for (int i : current) { 55 | bool pushed = false; 56 | for (int j = 0; j < n && excess[i]; j++) { 57 | if (capacity[i][j] - flow[i][j] > 0 && height[i] == height[j] + 1) { 58 | push(i, j); 59 | pushed = true; 60 | } 61 | } 62 | if (!pushed) { 63 | relabel(i); 64 | break; 65 | } 66 | } 67 | } 68 | 69 | int max_flow = 0; 70 | for (int i = 0; i < n; i++) 71 | max_flow += flow[0][i]; 72 | return max_flow; 73 | } -------------------------------------------------------------------------------- /cpp/Graph/topological_sort_and_cycle_detection.cpp: -------------------------------------------------------------------------------- 1 | // return empty vector if cycle detected 2 | // assumes nodes numbered from [1, n], can change lims for [0, n] in for loop 3 | vector findTopSort(int n, vector *adj) 4 | { 5 | vector inProcess(n + 1, 0), seen(n + 1, 0); 6 | vector topo; 7 | bool cycleFound = 0; 8 | 9 | function dfs = [&](int cur) { 10 | inProcess[cur] = 1; 11 | for(auto child : adj[cur]) { 12 | if (seen[child]) { 13 | continue; 14 | } else if (inProcess[child]) { 15 | cycleFound = 1; 16 | } else { 17 | dfs(child); 18 | } 19 | } 20 | inProcess[cur] = 0; 21 | seen[cur] = 1; 22 | topo.pb(cur); 23 | }; 24 | 25 | for (int i = 1; i <= n; ++i) { 26 | if (seen[i]) { 27 | continue; 28 | } 29 | dfs(i); 30 | } 31 | 32 | if (cycleFound) { 33 | topo.clear(); 34 | } 35 | return topo; 36 | } -------------------------------------------------------------------------------- /cpp/Number Theory/crt restore.cpp: -------------------------------------------------------------------------------- 1 | //attributation: https://www.hackerrank.com/rest/contests/w23/challenges/sasha-and-swaps-ii/hackers/ffao/download_solution 2 | long long crt(const vector< pair >& a, int mod) { 3 | long long res = 0; 4 | long long mult = 1; 5 | 6 | int SZ = a.size(); 7 | vector x(SZ); 8 | for (int i = 0; i &num, vector &rem) 25 | { 26 | ll prod=1; 27 | for(auto i:num) prod*=i; 28 | int n=rem.size(); 29 | ll ans=0, pp; 30 | for(int i=0; i hash; 19 | int mid = ((int)sqrt(1.0 * m) + 1); 20 | long long base = b; 21 | for(int i=0;isecond + cnt; 35 | } 36 | } -------------------------------------------------------------------------------- /cpp/Number Theory/discrete log.cpp: -------------------------------------------------------------------------------- 1 | ll power(ll x, ll y, ll m) 2 | { 3 | if (y==0) return 1; 4 | ll p=power(x, y/2, m)%m; 5 | p=p*p%m; 6 | return (y%2==0)?p:(x*p)%m; 7 | } 8 | 9 | ll modInverse(ll a, ll m) 10 | { 11 | return power(a, m-2, m); 12 | } 13 | 14 | //return x s.t a^x=b mod(prime) 15 | int discreteLog(int a, int b, int mod) 16 | { 17 | if(b==1) return 0; 18 | int middle=sqrt(mod)+1; 19 | 20 | unordered_map rem; 21 | rem.reserve(middle); 22 | rem.max_load_factor(.25); 23 | 24 | ll inv=modInverse(a, mod); 25 | ll cur=1; 26 | 27 | for(int r=0; r fac, ifac; 2 | 3 | void prefac(int N) 4 | { 5 | fac.resize(N); 6 | ifac.resize(N); 7 | fac[0]=1; 8 | 9 | for (int i = 1; i < N; ++i) { 10 | fac[i] = modint(i) * fac[i-1]; 11 | } 12 | 13 | ifac[N - 1] = fac[N-1].inv(); 14 | for (int i = N - 2; i >= 0; --i) { 15 | ifac[i] = modint(i + 1) * ifac[i+1]; 16 | } 17 | } 18 | 19 | modint npr(int n, int r) 20 | { 21 | if (r > n) 22 | return 0; 23 | return fac[n] * ifac[n - r]; 24 | } 25 | 26 | modint ncr(int n, int r) 27 | { 28 | if (r > n) 29 | return 0; 30 | return npr(n, r) * ifac[r]; 31 | } -------------------------------------------------------------------------------- /cpp/Number Theory/fast_factorization.cpp: -------------------------------------------------------------------------------- 1 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 2 | /* 3 | taken from: https://discuss.codechef.com/t/mdswin-editorial/44120 4 | miller_rabin to quickly check if a number is prime 5 | SPRP is a proven list of witnesses that can check prime for 6 | number upto 1e18 7 | */ 8 | 9 | inline ll mul(ll a, ll b, ll mod) 10 | { 11 | a %= mod; 12 | b %= mod; 13 | if(mod <= 2e9) return a*b%mod; 14 | ll res = 0; 15 | while (b > 0){ 16 | if (b % 2 == 1) res = (res + a) % mod; 17 | a = (a * 2) % mod; 18 | b /= 2; 19 | } 20 | return res % mod; 21 | } 22 | 23 | inline ll power(ll x, ll n, ll m) 24 | { 25 | ll res = 1; 26 | while (n){ 27 | if (n & 1) res = mul(res, x, m); 28 | x = mul(x, x, m); 29 | n >>= 1; 30 | } 31 | return (res % m); 32 | } 33 | 34 | ll SPRP[7] = {2LL, 325LL, 9375LL, 28178LL, 450775LL, 9780504LL, 1795265022LL}; 35 | bool miller_rabin(ll p, int t = 7) //t = 7 for SPRP base 36 | { 37 | if(p < 4) return (p > 1); 38 | if(!(p & 1LL)) return false; 39 | ll x = p - 1; 40 | int e = __builtin_ctzll(x); 41 | x >>= e; 42 | while(t--){ 43 | //ll witness = (rng() % (p-3)) + 2; //Using random witness 44 | ll witness = SPRP[t]; 45 | witness = power(witness%p, x, p); 46 | if(witness <= 1) continue; 47 | for(int i = 0; i lp(N1+1, 0), prime; 60 | 61 | void seive() 62 | { 63 | for(int i=2; i<=N1; ++i){ 64 | if(lp[i]==0){ 65 | lp[i]=i; 66 | prime.push_back(i); 67 | } 68 | for(auto j:prime){ 69 | if(j>lp[i] || i*j>N1) break; 70 | lp[i*j]=j; 71 | } 72 | } 73 | } 74 | 75 | inline ll rho(ll n) 76 | { 77 | if(n==1 or miller_rabin(n)) return n; 78 | if(n%2==0) return 2; 79 | ll x = rng()%(n-2)+2; 80 | ll y = x; 81 | ll c = rng()%(n-1)+1; 82 | ll d = 1; 83 | while(d==1){ 84 | x = (power(x,2,n)+c+n)%n; 85 | y = (power(y,2,n)+c+n)%n; 86 | y = (power(y,2,n)+c+n)%n; 87 | d = __gcd(abs(x-y),n); 88 | if(d==n) return rho(n); 89 | } 90 | return d; 91 | } 92 | 93 | //returns prime factors 94 | inline vll factorize(ll n) 95 | { 96 | if(first_run){ 97 | seive(); 98 | first_run=0; 99 | } 100 | ll dv = n; 101 | vector prmDiv; 102 | while(n>1){ 103 | bool p=0; 104 | if(n<=N1) dv=lp[n], p=1; 105 | else dv = rho(n); 106 | n = n/dv; 107 | if(p || miller_rabin(dv)) prmDiv.push_back(dv); 108 | else{ 109 | for(ll i=2; i*i<=dv; i++){ 110 | if(dv%i==0){ 111 | prmDiv.push_back(i); 112 | while(dv%i==0) 113 | dv/=i; 114 | } 115 | } 116 | if(dv>1) prmDiv.push_back(dv); 117 | } 118 | } 119 | sort(all(prmDiv)); 120 | prmDiv.erase(unique(all(prmDiv)), prmDiv.end()); 121 | return prmDiv; 122 | } 123 | } -------------------------------------------------------------------------------- /cpp/Number Theory/generator.cpp: -------------------------------------------------------------------------------- 1 | int generator(int p) 2 | { 3 | //find unique prime factors 4 | vector fac; 5 | int x=p-1; 6 | while(x!=1){ 7 | int f=lp[x]; 8 | while(x%f==0) x/=f; 9 | fac.pb(f); 10 | } 11 | 12 | for(int g=2; g 0){ 15 | if (b % 2 == 1) res = (res + a) % mod; 16 | a = (a * 2) % mod; 17 | b /= 2; 18 | } 19 | return res % mod; 20 | } 21 | 22 | inline ll power(ll x, ll n, ll m) 23 | { 24 | ll res = 1; 25 | while (n){ 26 | if (n & 1) res = mul(res, x, m); 27 | x = mul(x, x, m); 28 | n >>= 1; 29 | } 30 | return (res % m); 31 | } 32 | 33 | ll SPRP[7] = {2LL, 325LL, 9375LL, 28178LL, 450775LL, 9780504LL, 1795265022LL}; 34 | bool miller_rabin(ll p, int t = 7) //t = 7 for SPRP base 35 | { 36 | if(p < 4) return (p > 1); 37 | if(!(p & 1LL)) return false; 38 | ll x = p - 1; 39 | int e = __builtin_ctzll(x); 40 | x >>= e; 41 | while(t--){ 42 | //ll witness = (rng() % (p-3)) + 2; //Using random witness 43 | ll witness = SPRP[t]; 44 | witness = power(witness%p, x, p); 45 | if(witness <= 1) continue; 46 | for(int i = 0; ilp[i] || i*j>N1) break; 14 | lp[i*j]=j; 15 | } 16 | a=lp[i], b=i/lp[i]; 17 | if(b==1) mu[i]=-1; 18 | else if(__gcd(a, b)!=1) mu[i]=0; 19 | else mu[i]=mu[a]*mu[b]; 20 | } 21 | } -------------------------------------------------------------------------------- /cpp/Number Theory/modint.cpp: -------------------------------------------------------------------------------- 1 | // attributaion: cp-algorithms.com 2 | template 3 | T bpow(T x, int64_t n) { 4 | return n ? n % 2 ? x * bpow(x, n - 1) : bpow(x * x, n / 2) : T(1); 5 | } 6 | 7 | template 8 | struct modular { 9 | int64_t r; 10 | modular() : r(0) {} 11 | modular(int64_t rr) : r(rr) {if(abs(r) >= m) r %= m; if(r < 0) r += m;} 12 | modular inv() const {return bpow(*this, m - 2);} 13 | modular operator * (const modular &t) const {return (r * t.r) % m;} 14 | modular operator / (const modular &t) const {return *this * t.inv();} 15 | modular operator += (const modular &t) {r += t.r; if(r >= m) r -= m; return *this;} 16 | modular operator -= (const modular &t) {r -= t.r; if(r < 0) r += m; return *this;} 17 | modular operator + (const modular &t) const {return modular(*this) += t;} 18 | modular operator - (const modular &t) const {return modular(*this) -= t;} 19 | modular operator *= (const modular &t) {return *this = *this * t;} 20 | modular operator /= (const modular &t) {return *this = *this / t;} 21 | 22 | bool operator == (const modular &t) const {return r == t.r;} 23 | bool operator != (const modular &t) const {return r != t.r;} 24 | 25 | operator int64_t() const {return r;} 26 | }; 27 | template 28 | istream& operator >> (istream &in, modular &x) { 29 | return in >> x.r; 30 | } 31 | 32 | const int mod = 1e9 + 7; 33 | 34 | typedef modular modint; -------------------------------------------------------------------------------- /cpp/Number Theory/modinv.cpp: -------------------------------------------------------------------------------- 1 | ll power(ll x, ll y, ll m) 2 | { 3 | if(!y) return 1; 4 | ll p=power(x, y>>1, m)%m; 5 | p=p*p%m; 6 | return (y&1)?(x*p)%m:p; 7 | } 8 | ll modInverse(ll a, ll m) 9 | { return power(a, m-2, m); } -------------------------------------------------------------------------------- /cpp/Number Theory/modinvex.cpp: -------------------------------------------------------------------------------- 1 | ll gex(ll a, ll b, ll &x, ll &y) 2 | { 3 | if(!a){ 4 | x=0; 5 | y=1; 6 | return b; 7 | } 8 | 9 | ll x1, y1; 10 | ll g=gex(b%a, a, x1, y1); 11 | x=y1-(b/a)*x1; 12 | y=x1; 13 | return g; 14 | } 15 | 16 | ll inv(ll a, ll m) 17 | { 18 | ll x, y; 19 | ll g=gex(a, m, x, y); 20 | assert(g==1); 21 | return (x%m+m)%m; 22 | } -------------------------------------------------------------------------------- /cpp/Number Theory/primes: -------------------------------------------------------------------------------- 1 | 1000000007 2 | 1000000009 3 | 1000000021 4 | 1000000033 5 | 1000000087 6 | 1000000093 7 | 1000000097 8 | 1000000103 9 | 1000000123 10 | 1000000181 11 | 1000000207 12 | 1000000223 13 | 1000000241 14 | 1000000271 15 | 1000000289 16 | 1000000297 17 | 1000000321 18 | 1000000349 19 | 1000000363 20 | 1000000403 21 | 1000000409 22 | 1000000411 23 | 1000000427 24 | 1000000433 25 | 1000000439 26 | 1000000447 27 | 1000000453 28 | 1000000459 29 | 1000000483 30 | 1000000513 31 | 1000000531 32 | 1000000579 33 | 1000000607 34 | 1000000613 35 | 1000000637 36 | 1000000663 37 | 1000000711 38 | 1000000753 39 | 1000000787 40 | 1000000801 41 | 1000000829 42 | 1000000861 43 | 1000000871 44 | 1000000891 45 | 1000000901 46 | 1000000919 47 | 1000000931 48 | 1000000933 49 | 1000000993 50 | 1000001011 51 | 1000001021 52 | 1000001053 53 | 1000001087 54 | 1000001099 55 | 1000001137 56 | 1000001161 57 | 1000001203 58 | 1000001213 59 | 1000001237 60 | 1000001263 61 | 1000001269 62 | 1000001273 63 | 1000001279 64 | 1000001311 65 | 1000001329 66 | 1000001333 67 | 1000001351 68 | 1000001371 69 | 1000001393 70 | 1000001413 71 | 1000001447 72 | 1000001449 73 | 1000001491 74 | 1000001501 75 | 1000001531 76 | 1000001537 77 | 1000001539 78 | 1000001581 79 | 1000001617 80 | 1000001621 81 | 1000001633 82 | 1000001647 83 | 1000001663 84 | 1000001677 85 | 1000001699 86 | 1000001759 87 | 1000001773 88 | 1000001789 89 | 1000001791 90 | 1000001801 91 | 1000001803 92 | 1000001819 93 | 1000001857 94 | 1000001887 95 | 1000001917 96 | 1000001927 97 | 1000001957 98 | 1000001963 99 | 1000001969 100 | 1000002043 101 | -------------------------------------------------------------------------------- /cpp/Number Theory/seive O(n).cpp: -------------------------------------------------------------------------------- 1 | //taken from cp-algorithms.com 2 | 3 | const int N1=1e7; 4 | 5 | vector lp(N1+1, 0), prime; 6 | 7 | void seive() 8 | { 9 | for(int i=2; i<=N1; ++i){ 10 | if(lp[i]==0){ 11 | lp[i]=i; 12 | prime.push_back(i); 13 | } 14 | for(auto j:prime){ 15 | if(j>lp[i] || i*j>N1) break; 16 | lp[i*j]=j; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /cpp/Number Theory/solovay_strasson_primality_check.cpp: -------------------------------------------------------------------------------- 1 | ll power(ll x, ll y, ll m) 2 | { 3 | if (y==0) return 1; 4 | ll p=power(x, y/2, m)%m; 5 | p=(p*p)%m; 6 | return (y%2==0)?p:(x*p)%m; 7 | } 8 | 9 | int jacobi(ll n, ll k) 10 | { 11 | assert(k>0 && k%2==1); 12 | n%=k; 13 | int sig=1; 14 | while(n){ 15 | int r=k%8; 16 | while(n%2==0){ 17 | n/=2; 18 | if(r==3 || r==5) sig=-sig; 19 | } 20 | swap(n, k); 21 | if(n%4==k%4 && k%4==3) sig=-sig; 22 | n%=k; 23 | } 24 | if(k==1) return sig; 25 | return 0; 26 | } 27 | 28 | bool isprime(ll p) 29 | { 30 | if(p==2) return 1; 31 | if(p%2==0 || p<=1) return 0; 32 | int itr=10; 33 | while(itr--){ 34 | ll a=1LL*rand()*rand()%p; 35 | while(!a) a=1LL*rand()*rand()%p; 36 | if(__gcd(a, p)!=1) return 0; 37 | ll j=jacobi(a, p); 38 | if(!j) return 0; 39 | if(j<0) j+=p; 40 | if(power(a, (p>>1), p)!=j) return 0; 41 | } 42 | return 1; 43 | } -------------------------------------------------------------------------------- /cpp/Number Theory/totient seive.cpp: -------------------------------------------------------------------------------- 1 | //taken from geeksforgeeks 2 | const int N = 1e7 + 1; 3 | 4 | int phi[N]; 5 | 6 | void computeTotient(int n) { 7 | for (int i = 1; i <= n; i++) phi[i] = i; 8 | for (int p = 2; p <= n; p++) { 9 | if (phi[p] == p) { 10 | phi[p] = p - 1; 11 | 12 | for (int i = 2 * p; i <= n; i += p) { 13 | phi[i] = (phi[i] / p) * (p - 1); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /cpp/Optimization/simulatedAnnealing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pb push_back 3 | #define all(x) x.begin(), x.end() 4 | #define pii pair 5 | 6 | using namespace std; 7 | 8 | int n; 9 | 10 | const int N=1001; 11 | 12 | bool arr[N][N]; 13 | int n1[N][N]={}, n0[N][N]={}; 14 | 15 | auto st=clock(); 16 | 17 | inline double ctime() 18 | { 19 | return double(clock()-st)/CLOCKS_PER_SEC; 20 | } 21 | 22 | struct node{ 23 | int i1, j1, i2, j2; 24 | bool operator==(node n2) 25 | { 26 | return (i1==n2.i1 && i2==n2.i2 27 | && j1==n2.j1 && j2==n2.j2); 28 | } 29 | }; 30 | 31 | node usd1[N][N]; 32 | vector ans, vec; 33 | 34 | node getRandom() 35 | { 36 | int ht=rand()%(n/10)+1, wid=rand()%(n/8)+1; 37 | int ci=rand()%(n-ht)+1, cj=rand()%(n-wid)+1; 38 | return {ci, cj, ci+ht-1, cj+wid-1}; 39 | } 40 | 41 | inline int area(node n1) 42 | { 43 | return (n1.i2-n1.i1+1)*(n1.j2-n1.j1+1); 44 | } 45 | 46 | inline int score(node n) 47 | { 48 | int a1=n1[n.i2][n.j2]-n1[n.i1-1][n.j2]-n1[n.i2][n.j1-1]+n1[n.i1-1][n.j1-1]; 49 | int a0=n0[n.i2][n.j2]-n0[n.i1-1][n.j2]-n0[n.i2][n.j1-1]+n0[n.i1-1][n.j1-1]; 50 | return abs(a1-a0); 51 | } 52 | 53 | double acceptanceProbability(double cScore, double nScore, double T) 54 | { 55 | double x=(nScore-cScore)/T; 56 | return exp(x); 57 | } 58 | 59 | int cal(node n) 60 | { 61 | vec.clear(); 62 | int di=n.i2-n.i1+1, dj=n.j2-n.j1+1; 63 | for(auto i:ans){ 64 | if(i==usd1[di][dj]) continue; 65 | if(n.i2 dist(0, 1); 91 | int currentScore=0, itr=100; 92 | while(ctime()dist(rnd)){ 101 | apply(newSol); 102 | currentScore=newScore; 103 | } 104 | } 105 | } 106 | return ; 107 | } 108 | 109 | int main() 110 | { 111 | //freopen("in.txt" , "r" , stdin) ; 112 | //freopen("out.txt" , "w" , stdout) ; 113 | ios_base::sync_with_stdio(false); 114 | //srand(236); 115 | cin>>n; 116 | for(int i=1; i<=n; ++i){ 117 | for(int j=1; j<=n; ++j){ 118 | cin>>arr[i][j]; 119 | usd1[i][j]={0, 0, 0, 0}; 120 | } 121 | } 122 | 123 | for(int i=1; i<=n; ++i){ 124 | for(int j=1; j<=n; ++j){ 125 | n1[i][j]=n1[i-1][j]+n1[i][j-1]-n1[i-1][j-1]+(arr[i][j]==1); 126 | n0[i][j]=n0[i-1][j]+n0[i][j-1]-n0[i-1][j-1]+(arr[i][j]==0); 127 | } 128 | } 129 | 130 | anneal(); 131 | 132 | cout< prefix_function(string s) 2 | { 3 | int n=(int)s.length(); 4 | vector pi(n); 5 | for (int i=1; i0 && s[i]!=s[j]) j=pi[j-1]; 8 | if (s[i]==s[j]) j++; 9 | pi[i] = j; 10 | } 11 | return pi; 12 | } 13 | -------------------------------------------------------------------------------- /cpp/Strings/manachers.cpp: -------------------------------------------------------------------------------- 1 | void manachers(string &s, vi &d1, vi &d2) 2 | { 3 | int n=s.size(); 4 | d1.resize(n); 5 | for (int i=0, l=0, r=-1; ir) ? 1 : min(d1[l+r-i], r-i); 7 | while (i-k>=0 && i+kr) l=i-k, r=i+k; 10 | } 11 | d2.resize(n); 12 | for (int i=0, l=0, r=-1; ir) ? 0 : min(d2[l+r-i+1], r-i+1); 14 | while (i-k-1>=0 && i+kr) l=i-k-1, r=i+k; 17 | } 18 | } -------------------------------------------------------------------------------- /cpp/Strings/rolling hash.cpp: -------------------------------------------------------------------------------- 1 | ll power(ll x, ll y, ll m) 2 | { 3 | if (y==0) return 1; 4 | ll p=power(x, y>>1, m)%m; 5 | p=p*p%m; 6 | return (y&1)?(x*p)%m:p; 7 | } 8 | ll modInverse(ll a, ll m) 9 | { return power(a, m-2, m); } 10 | 11 | /* 12 | creates rolling hash on vector with elements in [1, 28] 13 | Query hash of segment [l, r] 14 | To check if palindrome, compare query(l, r)==query(l, r, 1) 15 | */ 16 | 17 | struct rollingHash{ 18 | const int mod=1000000459; 19 | int n; 20 | vi hsh[2]; 21 | vll ip29, p29; 22 | 23 | void pre(vi &vec, vi &hsh) 24 | { 25 | hsh.resize(n); 26 | hsh[0]=vec[0]; 27 | for(int i=1; i=0; ip29[i]=29*ip29[i+1]%mod, --i); 39 | 40 | pre(vec, hsh[0]); 41 | if(!rev) return ; 42 | reverse(all(vec)); 43 | pre(vec, hsh[1]); 44 | reverse(all(hsh[1])); 45 | } 46 | 47 | int query(int l, int r, bool rev=0) 48 | { 49 | if(!rev) return l ? (hsh[0][r]-hsh[0][l-1]+mod)*ip29[l]%mod : hsh[0][r]; 50 | return r 3 | struct RMQ { 4 | int n = 0, levels = 0; 5 | vector> range_min; 6 | 7 | RMQ(const vector &values = {}) { 8 | if (!values.empty()) 9 | build(values); 10 | } 11 | 12 | static int largest_bit(int x) { 13 | return 31 - __builtin_clz(x); 14 | } 15 | 16 | static T better(T a, T b) { 17 | return maximum_mode ? max(a, b) : min(a, b); 18 | } 19 | 20 | void build(const vector &values) { 21 | n = values.size(); 22 | levels = largest_bit(n) + 1; 23 | range_min.resize(levels); 24 | 25 | for (int k = 0; k < levels; k++) 26 | range_min[k].resize(n - (1 << k) + 1); 27 | 28 | if (n > 0) 29 | range_min[0] = values; 30 | 31 | for (int k = 1; k < levels; k++) 32 | for (int i = 0; i <= n - (1 << k); i++) 33 | range_min[k][i] = better(range_min[k - 1][i], range_min[k - 1][i + (1 << (k - 1))]); 34 | } 35 | 36 | T query_value(int a, int b) const { 37 | assert(0 <= a && a <= b && b < n); 38 | int level = largest_bit(b - a + 1); 39 | return better(range_min[level][a], range_min[level][b + 1 - (1 << level)]); 40 | } 41 | }; 42 | 43 | template 44 | struct suffix_array{ 45 | int n, C; 46 | T_string str; 47 | vi p, rank, lcp; 48 | RMQ rmq; 49 | 50 | void build_suffix_array() 51 | { 52 | if(C <= 256) str.pb(0); 53 | else str.pb(-1); 54 | 55 | ++n; 56 | p.resize(n); 57 | vi c(n); 58 | vi cnt(max(n, C), 0); 59 | 60 | if(C < 256){ 61 | for(int i = 0; i < n; ++i) 62 | ++cnt[str[i]]; 63 | for(int i = 0; i < n; ++i) 64 | p[--cnt[str[i]]] = i; 65 | } else{ 66 | iota(p.begin(), p.end(), 0); 67 | sort(all(p), [&](int a, int b){ 68 | return str[a] < str[b]; 69 | }); 70 | } 71 | 72 | int classes = 1; 73 | c[p[0]] = 0; 74 | 75 | for(int i=1; i= len ? p[i] - len : p[i] - len + n; 83 | 84 | fill(cnt.begin(), cnt.begin() + classes, 0); 85 | 86 | for(int i = 0; i < n; ++i) 87 | ++cnt[c[pn[i]]]; 88 | 89 | for(int i = 1; i < classes; ++i) 90 | cnt[i] += cnt[i-1]; 91 | 92 | for(int i = n-1; i >= 0; --i) 93 | p[--cnt[c[pn[i]]]] = pn[i]; 94 | 95 | cn[p[0]] = 0; 96 | classes = 1; 97 | pii prev = {c[p[0]], c[(p[0] + len) % n]}; 98 | 99 | for(int i = 1; i < n; ++i){ 100 | pii cur = {c[p[i]], c[(p[i] + len) % n]}; 101 | cn[p[i]] = cur == prev ? classes - 1 : classes++; 102 | prev = cur; 103 | } 104 | c.swap(cn); 105 | } 106 | 107 | --n; 108 | str.ppb(); 109 | p.erase(p.begin()); 110 | } 111 | 112 | void build_lcp() 113 | { 114 | rank.resize(n); 115 | for (int i = 0; i < n; ++i) 116 | rank[p[i]] = i; 117 | 118 | int k = 0; 119 | lcp.resize(n-1, 0); 120 | for (int i = 0; i < n; ++i) { 121 | if (rank[i] == n - 1) { 122 | k = 0; 123 | continue; 124 | } 125 | int j = p[rank[i] + 1]; 126 | while(i + k < n && j + k < n && str[i+k] == str[j+k]) 127 | k++; 128 | lcp[rank[i]] = k; 129 | if(k) k--; 130 | } 131 | } 132 | 133 | suffix_array(const T_string &_str, bool need_rmq = true, int _C = 256) 134 | { 135 | str = _str, C = _C, n = _str.size(); 136 | build_suffix_array(); 137 | if(need_rmq && n > 1) 138 | build_lcp(), rmq.build(lcp); 139 | } 140 | 141 | // 0 indexing 142 | int get_lcp(int a, int b) 143 | { 144 | if(a == b) return n - a; 145 | a = rank[a], b = rank[b]; 146 | if(a > b) swap(a, b); 147 | return rmq.query_value(a, b - 1); 148 | } 149 | 150 | int compare(int a, int b, int len) 151 | { 152 | int match = get_lcp(a, b); 153 | if(match >= len) return 0; 154 | if(a + match >= n || b + match >= n) return a > b ? -1 : 1; 155 | return str[a + match] > str[b + match] ? 1 : -1; 156 | } 157 | }; -------------------------------------------------------------------------------- /cpp/Strings/z function.cpp: -------------------------------------------------------------------------------- 1 | //attribution: cp-algorithms.com 2 | vector z_function(string s) 3 | { 4 | int n = (int)s.size(); 5 | vector z(n); 6 | for (int i = 1, l = 0, r = 0; i < n; ++i) { 7 | if (i <= r) 8 | z[i] = min(r - i + 1, z[i - l]); 9 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) 10 | ++z[i]; 11 | if (i + z[i] - 1 > r) 12 | l = i, r = i + z[i] - 1; 13 | } 14 | return z; 15 | } 16 | -------------------------------------------------------------------------------- /cpp/comparator struct.cpp: -------------------------------------------------------------------------------- 1 | struct comp{ 2 | bool operator()(const char c1, const char c2) 3 | { 4 | return c1 distribution(0,9); 4 | x=distribution(rng); -------------------------------------------------------------------------------- /cpp/stack_size.txt: -------------------------------------------------------------------------------- 1 | Windows: 2 | https://stackoverflow.com/questions/54821412/how-to-increase-stack-size-when-compiling-a-c-program-using-mingw-compiler 3 | g++ -Wl,--stack,16777216 -o file.exe file.cpp 4 | Sets stack size to 16777216 bytes 5 | 6 | On Linux, to get an unlimited stack, you should open a shell and run this command: 7 | $ ulimit -s unlimited 8 | And then (until you close that shell) the stack limit for that shell (and for the commands you will call from inside that shell, like ./program < input.txt and so on) will be unlimited. -------------------------------------------------------------------------------- /cpp/template.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Arjan Singh Bal, IIITM Gwalior 3 | "Everything in this world is magic, except to the magician" 4 | */ 5 | 6 | #include 7 | #ifdef LOCAL 8 | #include "pprint.hpp" 9 | #endif 10 | 11 | using namespace std; 12 | 13 | template 14 | void prn(Arg1&& arg1) 15 | { cout< 17 | void prn(Arg1&& arg1, Args&&... args) 18 | { cout< 21 | void prs(Arg1&& arg1) 22 | { cout< 24 | void prs(Arg1&& arg1, Args&&... args) 25 | { cout< 28 | void read(Arg1&& arg1) 29 | { cin>>arg1; } 30 | template 31 | void read(Arg1&& arg1, Args&&... args) 32 | { cin>>arg1; read(args...); } 33 | 34 | #define ll long long 35 | #define pii pair 36 | #define pli pair 37 | #define pil pair 38 | #define pll pair 39 | #define vi vector 40 | #define vll vector 41 | #define vb vector 42 | #define vd vector 43 | #define vs vector 44 | #define ff first 45 | #define ss second 46 | #define pb push_back 47 | #define eb emplace_back 48 | #define ppb pop_back 49 | #define pf push_front 50 | #define ppf pop_front 51 | #define vpii vector 52 | #define umap unordered_map 53 | #define all(x) x.begin(),x.end() 54 | #define clr(a,b) memset(a,b,sizeof a) 55 | #define fr(i, n) for(int i=0; i=0; --i) 58 | #define precise(x) cout< func(l2)) r = l2; 15 | else l = l1; 16 | } 17 | 18 | double x = l; 19 | return func(x); 20 | } 21 | 22 | // works faster than ternary version 23 | inline ll ternarySearch(ll start, ll end) 24 | { 25 | while (start < end) { 26 | ll mid = (start + end) / 2; 27 | if (cost(mid) > cost(mid + 1)) { 28 | end = mid; 29 | } else { 30 | start = mid + 1; 31 | } 32 | } 33 | return cost(start); 34 | } 35 | 36 | inline ll ternarySearch(ll start, ll end) 37 | { 38 | while (start < end) { 39 | ll mid1 = start + (end - start) / 3; 40 | ll mid2 = end - (end - start) / 3; 41 | if (cost(mid1) > cost(mid2)) { 42 | end = mid2 - 1; 43 | } else { 44 | start = mid1 + 1; 45 | } 46 | } 47 | return cost(start); 48 | } 49 | 50 | int ternary_search(int l,int r, int x) 51 | { 52 | if(r>=l) 53 | { 54 | int mid1 = l + (r - l)/3; 55 | int mid2 = r - (r - l)/3; 56 | if(ar[mid1] == x) 57 | return mid1; 58 | if(ar[mid2] == x) 59 | return mid2; 60 | if(xar[mid2]) 63 | return ternary_search(mid2+1,r,x); 64 | else 65 | return ternary_search(mid1+1,mid2-1,x); 66 | 67 | } 68 | return -1; 69 | } -------------------------------------------------------------------------------- /cpp/time.cpp: -------------------------------------------------------------------------------- 1 | auto st=clock(); 2 | 3 | inline float ctime() 4 | { 5 | return float(clock()-st)/CLOCKS_PER_SEC; 6 | } -------------------------------------------------------------------------------- /cpp/trace.cpp: -------------------------------------------------------------------------------- 1 | #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__) 2 | template 3 | void __f(const char* name, Arg1&& arg1){ 4 | cerr << name << " : " << arg1 << std::endl; 5 | } 6 | template 7 | void __f(const char* names, Arg1&& arg1, Args&&... args){ 8 | const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...); 9 | } -------------------------------------------------------------------------------- /python/stack+recursion.py: -------------------------------------------------------------------------------- 1 | import resource, sys 2 | resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1)) 3 | sys.setrecursionlimit(10**6) -------------------------------------------------------------------------------- /python/template.py: -------------------------------------------------------------------------------- 1 | import sys 2 | #sys.stdin=open("in.txt", "r") 3 | #sys.stdout=open(‘output.txt’,‘w’) 4 | import math -------------------------------------------------------------------------------- /rust/data_structures/dsu.rs: -------------------------------------------------------------------------------- 1 | struct DSU { 2 | parent: Vec, 3 | component_size: Vec, 4 | num_comps: usize, 5 | } 6 | 7 | impl DSU { 8 | fn root(&mut self, x: usize) -> usize { 9 | if x == self.parent[x] { 10 | return x; 11 | } 12 | self.parent[x] = self.root(self.parent[x]); 13 | self.parent[x] 14 | } 15 | 16 | fn merge(&mut self, c1: usize, c2: usize) -> bool { 17 | let mut r1 = self.root(c1); 18 | let mut r2 = self.root(c2); 19 | if r1 == r2 { 20 | return false; 21 | } 22 | if self.component_size[r2] > self.component_size[r1] { 23 | swap(&mut r1, &mut r2); 24 | } 25 | self.parent[r2] = r1; 26 | self.component_size[r1] += self.component_size[r2]; 27 | self.num_comps -= 1; 28 | true 29 | } 30 | 31 | fn new(n: usize) -> DSU { 32 | DSU { 33 | parent: (0..n).map(|i| i).collect(), 34 | component_size: vec![1; n], 35 | num_comps: n, 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /rust/data_structures/queue.rs: -------------------------------------------------------------------------------- 1 | // A simple queue implementation with basic functions. 2 | // This doesn't free memory on pop operations! 3 | struct Queue { 4 | q: Vec, 5 | st: usize, 6 | } 7 | 8 | impl Queue { 9 | fn push(&mut self, val: T) { 10 | self.q.push(val); 11 | } 12 | 13 | fn pop(&mut self) -> T { 14 | if self.st >= self.q.len() { 15 | panic!("Cannot pop from empty queue!"); 16 | } 17 | self.st += 1; 18 | self.q[self.st - 1] 19 | } 20 | 21 | fn len(self) -> usize { 22 | return self.q.len() - self.st; 23 | } 24 | 25 | fn is_empty(&self) -> bool { 26 | return self.q.len() - self.st == 0; 27 | } 28 | 29 | fn new(capacity: usize) -> Queue { 30 | return Queue { 31 | q: Vec::with_capacity(capacity), 32 | st: 0, 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rust/data_structures/segment_tree.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Debug)] 2 | struct Node { 3 | value: i32, 4 | } 5 | 6 | impl Node { 7 | fn merge(&self, other: &Node) -> Node { 8 | Node { 9 | value: // logic to merge nodes 10 | } 11 | } 12 | } 13 | 14 | #[derive(Debug)] 15 | struct Res(i32); 16 | 17 | impl Res { 18 | fn merge(&self, other: &Res) -> Res { 19 | Res( 20 | // logic to merge results 21 | ) 22 | } 23 | } 24 | 25 | struct SegTree { 26 | tree: Vec, 27 | start: i32, 28 | end: i32, 29 | } 30 | 31 | struct SegTreeBuildCtx<'a> { 32 | vals: &'a Vec, 33 | } 34 | 35 | impl SegTree { 36 | fn query(&self, l: i32, r: i32) -> Res { 37 | self.query_range(self.start, self.end, 1, l, r) 38 | } 39 | 40 | fn update(&mut self, idx: i32, val: Node) { 41 | self.update_range(self.start, self.end, 1, val, idx); 42 | } 43 | 44 | fn query_range(&self, st: i32, en: i32, node: usize, l: i32, r: i32) -> Res { 45 | if st >= l && en <= r { 46 | return Res(self.tree[node].value); 47 | } 48 | let mid = (st + en) >> 1; 49 | let node_l = node << 1; 50 | let node_r = (node << 1) | 1; 51 | if r <= mid { 52 | return self.query_range(st, mid, node_l, l, r); 53 | } 54 | if l > mid { 55 | return self.query_range(mid + 1, en, node_r, l, r); 56 | } 57 | Res::merge( 58 | &self.query_range(st, mid, node_l, l, r), 59 | &self.query_range(mid + 1, en, node_r, l, r), 60 | ) 61 | } 62 | 63 | fn update_range(&mut self, st: i32, en: i32, node: usize, val: Node, idx: i32) { 64 | if en < idx || st > idx { 65 | return ; 66 | } 67 | if st == en { 68 | self.tree[node] = val; 69 | return ; 70 | } 71 | let mid = (st + en) >> 1; 72 | let node_l = node << 1; 73 | let node_r = (node << 1) | 1; 74 | if idx <= mid { 75 | self.update_range(st, mid, node_l, val, idx); 76 | } else { 77 | self.update_range(mid + 1, en, node_r, val, idx); 78 | } 79 | self.tree[node] = self.tree[node_l].merge(&self.tree[node_r]); 80 | } 81 | 82 | fn build_range(&mut self, st: i32, en: i32, node: usize, ctx: &SegTreeBuildCtx) { 83 | if st == en { 84 | self.tree[node] = Node { 85 | value: 0, 86 | }; 87 | return; 88 | } 89 | let mid = (st + en) >> 1; 90 | let node_l = node << 1; 91 | let node_r = (node << 1) | 1; 92 | self.build_range(st, mid, node_l, ctx); 93 | self.build_range(mid + 1, en, node_r, ctx); 94 | self.tree[node] = self.tree[node_l].merge(&self.tree[node_r]); 95 | } 96 | 97 | fn new(start: i32, end: i32, ctx: &SegTreeBuildCtx) -> SegTree { 98 | let len = 4 * (end - start + 1) as usize; 99 | let default_node = Node { 100 | value: 0, 101 | }; 102 | let mut st = SegTree { 103 | tree: vec![default_node; 4 * len], 104 | start, 105 | end, 106 | }; 107 | // st.build_range(start, end, 1, ctx); 108 | st 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /rust/data_structures/segment_tree_lazy_propagation.rs: -------------------------------------------------------------------------------- 1 | [derive(Clone, Debug, Copy)] 2 | enum Update { 3 | None, 4 | Assign, 5 | Xor, 6 | } 7 | 8 | #[derive(Clone, Debug)] 9 | struct Node { 10 | frequency: Vec, 11 | lazy: i32, 12 | update_type: Update, 13 | } 14 | 15 | impl Node { 16 | fn merge(&self, other: &Node) -> Node { 17 | let mut res = Node { 18 | frequency: vec![0; B], 19 | lazy: -1, 20 | update_type: Update::None, 21 | }; 22 | 23 | for i in 0..B { 24 | res.frequency[i] = self.frequency[i] + other.frequency[i]; 25 | } 26 | 27 | res 28 | } 29 | } 30 | 31 | #[derive(Debug)] 32 | struct Res(u64); 33 | 34 | impl Res { 35 | fn merge(&self, other: &Res) -> Res { 36 | Res(self.0 + other.0) 37 | } 38 | } 39 | 40 | struct SegTree { 41 | tree: Vec, 42 | start: i32, 43 | end: i32, 44 | } 45 | 46 | struct SegTreeBuildCtx<'a> { 47 | vals: &'a Vec, 48 | } 49 | 50 | impl SegTree { 51 | fn query(&mut self, l: i32, r: i32) -> Res { 52 | self.query_range(self.start, self.end, 1, l, r) 53 | } 54 | 55 | fn range_update(&mut self, l: i32, r: i32, delta: usize, update_type: Update) { 56 | self.update_range(self.start, self.end, 1, l, r, delta, update_type) 57 | } 58 | 59 | fn query_range(&mut self, st: i32, en: i32, node: usize, l: i32, r: i32) -> Res { 60 | if self.tree[node].lazy != -1 { 61 | self.apply_lazy(st, en, node); 62 | } 63 | if en < l || st > r { 64 | return Res(0); 65 | } 66 | if st >= l && en <= r { 67 | return Res(self.calculate(node)); 68 | } 69 | let mid = (st + en) >> 1; 70 | let node_l = node << 1; 71 | let node_r = (node << 1) | 1; 72 | self.query_range(st, mid, node_l, l, r) 73 | .merge(&self.query_range(mid + 1, en, node_r, l, r)) 74 | } 75 | 76 | fn calculate(&self, node: usize) -> u64 { 77 | let mut sum = 0; 78 | for bit in 0..B { 79 | sum += (1 << bit) as u64 * self.tree[node].frequency[bit] as u64; 80 | } 81 | sum 82 | } 83 | 84 | fn update_range( 85 | &mut self, 86 | st: i32, 87 | en: i32, 88 | node: usize, 89 | l: i32, 90 | r: i32, 91 | delta: usize, 92 | update_type: Update, 93 | ) { 94 | if self.tree[node].lazy != -1 { 95 | self.apply_lazy(st, en, node); 96 | } 97 | if en < l || st > r { 98 | return; 99 | } 100 | if st >= l && en <= r { 101 | self.tree[node].lazy = delta as i32; 102 | self.tree[node].update_type = update_type; 103 | self.apply_lazy(st, en, node); 104 | return; 105 | } 106 | let mid = (st + en) >> 1; 107 | let node_l = node << 1; 108 | let node_r = (node << 1) | 1; 109 | self.update_range(st, mid, node_l, l, r, delta, update_type); 110 | self.update_range(mid + 1, en, node_r, l, r, delta, update_type); 111 | self.tree[node] = self.tree[node_l].merge(&self.tree[node_r]); 112 | } 113 | 114 | fn apply_lazy(&mut self, st: i32, en: i32, node: usize) { 115 | let val = self.tree[node].lazy; 116 | if val == -1 { 117 | return; 118 | } 119 | let u_type = self.tree[node].update_type; 120 | match u_type { 121 | Update::Assign => { 122 | for i in 0..B { 123 | if (val >> i) & 1 == 1 { 124 | self.tree[node].frequency[i] = (en - st + 1) as usize; 125 | } else { 126 | self.tree[node].frequency[i] = 0; 127 | } 128 | } 129 | } 130 | Update::Xor => { 131 | for i in 0..B { 132 | if (val >> i) & 1 == 1 { 133 | self.tree[node].frequency[i] = 134 | (en - st + 1) as usize - self.tree[node].frequency[i]; 135 | } 136 | } 137 | } 138 | _ => (), 139 | } 140 | self.tree[node].lazy = -1; 141 | self.tree[node].update_type = Update::None; 142 | if st == en { 143 | return; 144 | } 145 | let node_l = node << 1; 146 | let node_r = (node << 1) | 1; 147 | match u_type { 148 | Update::None => (), 149 | Update::Assign => { 150 | self.tree[node_l].lazy = val; 151 | self.tree[node_r].lazy = val; 152 | self.tree[node_l].update_type = u_type; 153 | self.tree[node_r].update_type = u_type; 154 | } 155 | Update::Xor => { 156 | (self.tree[node_l].lazy, self.tree[node_l].update_type) = SegTree::combine_lazy( 157 | val, 158 | u_type, 159 | self.tree[node_l].lazy, 160 | self.tree[node_l].update_type, 161 | ); 162 | (self.tree[node_r].lazy, self.tree[node_r].update_type) = SegTree::combine_lazy( 163 | val, 164 | u_type, 165 | self.tree[node_r].lazy, 166 | self.tree[node_r].update_type, 167 | ); 168 | } 169 | } 170 | } 171 | 172 | fn combine_lazy(lazy1: i32, type1: Update, lazy2: i32, type2: Update) -> (i32, Update) { 173 | if lazy2 == -1 { 174 | return (lazy1, type1); 175 | } 176 | match type2 { 177 | Update::None => (lazy1, type1), 178 | Update::Assign|Update::Xor => match type1 { 179 | Update::None => panic!("Applying lazy with type1 as None"), 180 | Update::Assign => (lazy1, type1), 181 | Update::Xor => (lazy1 ^ lazy2, type2), 182 | }, 183 | } 184 | } 185 | 186 | fn build_range(&mut self, st: i32, en: i32, node: usize, ctx: &SegTreeBuildCtx) { 187 | if st == en { 188 | self.tree[node].lazy = ctx.vals[st as usize] as i32; 189 | self.tree[node].update_type = Update::Assign; 190 | self.tree[node].frequency = vec![0; B]; 191 | self.apply_lazy(st, en, node); 192 | return; 193 | } 194 | let mid = (st + en) >> 1; 195 | let node_l = node << 1; 196 | let node_r = (node << 1) | 1; 197 | self.build_range(st, mid, node_l, ctx); 198 | self.build_range(mid + 1, en, node_r, ctx); 199 | self.tree[node] = self.tree[node_l].merge(&self.tree[node_r]); 200 | } 201 | 202 | fn new(start: i32, end: i32, ctx: &SegTreeBuildCtx) -> SegTree { 203 | let len = 4 * (end - start + 1) as usize; 204 | let default_node = Node { 205 | frequency: Vec::new(), 206 | update_type: Update::None, 207 | lazy: -1, 208 | }; 209 | let mut st = SegTree { 210 | tree: vec![default_node; 4 * len], 211 | start, 212 | end, 213 | }; 214 | st.build_range(start, end, 1, ctx); 215 | st 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /rust/data_structures/trie.rs: -------------------------------------------------------------------------------- 1 | 2 | // incomplete implementation of a binary trie. 3 | struct Node { 4 | freq: usize, 5 | children: [Option; 2], 6 | } 7 | 8 | impl Node { 9 | fn new() -> Node { 10 | Node { 11 | freq: 0, 12 | children: [None, None], 13 | } 14 | } 15 | } 16 | 17 | struct Trie { 18 | nodes: Vec, 19 | depth: usize, 20 | } 21 | 22 | impl Trie { 23 | fn new(depth: usize) -> Trie { 24 | let root = Node::new(); 25 | Trie { 26 | nodes: vec![root], 27 | depth, 28 | } 29 | } 30 | 31 | fn insert(&mut self, val: usize) { 32 | let mut cur_idx = 0; 33 | for cur_depth in (0..self.depth).rev() { 34 | let mut cur_node = &mut self.nodes[cur_idx]; 35 | cur_node.freq += 1; 36 | let nxt = (val >> cur_depth) & 1; 37 | 38 | if let None = cur_node.children[nxt] { 39 | self.nodes[cur_idx].children[nxt] = Some(self.nodes.len()); 40 | self.nodes.push(Node::new()); 41 | } 42 | cur_idx = self.nodes[cur_idx].children[nxt].unwrap(); 43 | } 44 | } 45 | 46 | // Finds the number of elements in the trie that have a common prefix with target and are >= target. 47 | fn query(&self, target: usize) -> usize { 48 | let mut cur_idx = 0; 49 | let mut cur_ans = 0; 50 | 51 | for cur_depth in (0..self.depth).rev() { 52 | let cur_node = &self.nodes[cur_idx]; 53 | let nxt = (target >> cur_depth) & 1; 54 | 55 | 56 | if nxt == 0 { 57 | match cur_node.children[1] { 58 | Some(x) => cur_ans = max(cur_ans, self.nodes[x].freq), 59 | None => (), 60 | } 61 | } 62 | 63 | match cur_node.children[nxt] { 64 | Some(x) => cur_idx = x, 65 | None => break, 66 | } 67 | 68 | if ((1 << cur_depth) - 1) & target == 0 { 69 | cur_ans = max(cur_ans, self.nodes[cur_idx].freq); 70 | } 71 | } 72 | 73 | cur_ans 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /rust/graphs/dfs.rs: -------------------------------------------------------------------------------- 1 | struct DFSContext<'a> { 2 | adj: &'a Vec>, 3 | vals: &'a Vec, 4 | } 5 | 6 | fn dfs(cur: &usize, par: &usize, ctx: &mut DFSContext) { 7 | for i in &ctx.adj[*cur] { 8 | if i == par { 9 | continue; 10 | } 11 | dfs(&i, cur, ctx); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /rust/graphs/lca-binary-lifting.rs: -------------------------------------------------------------------------------- 1 | 2 | struct LCA { 3 | parent: Vec>, 4 | depth: Vec, 5 | log_n: usize, 6 | n: usize, 7 | } 8 | 9 | impl LCA { 10 | /* 11 | Adj list should be of size n + 1 and node numbers are in [1, n]. 12 | */ 13 | fn new(adj: &Vec>) -> LCA { 14 | let mut log_n = 1; 15 | let n = adj.len() - 1; 16 | while 1 << log_n < n { 17 | log_n += 1; 18 | } 19 | let mut depth = vec![0; n + 1]; 20 | let mut parent = vec![vec![0; n + 1]; log_n]; 21 | let mut q = VecDeque::new(); 22 | q.push_back(1); 23 | 24 | let mut populate = |cur: usize, par: usize, parent: &mut Vec>| { 25 | parent[0][cur] = par; 26 | depth[cur] = depth[par] + 1; 27 | let mut prev_par = par; 28 | for j in 1..log_n { 29 | if prev_par == 0 { 30 | break; 31 | } 32 | parent[j][cur] = parent[j - 1][prev_par]; 33 | prev_par = parent[j][cur]; 34 | } 35 | }; 36 | 37 | while !q.is_empty() { 38 | let cur = q.pop_front().unwrap(); 39 | for &child in &adj[cur] { 40 | if child == parent[0][cur] { 41 | continue; 42 | } 43 | populate(child, cur, &mut parent); 44 | q.push_back(child); 45 | } 46 | } 47 | 48 | LCA { 49 | parent, 50 | depth, 51 | log_n, 52 | n, 53 | } 54 | } 55 | 56 | fn get_lca(&self, mut u: usize, mut v: usize) -> usize { 57 | if self.depth[v] < self.depth[u] { 58 | std::mem::swap(&mut u, &mut v); 59 | } 60 | 61 | let dif = self.depth[v] - self.depth[u]; 62 | for i in 0..self.log_n { 63 | if (dif >> i) & 1 == 1 { 64 | v = self.parent[i][v]; 65 | } 66 | } 67 | 68 | if u == v { 69 | return u; 70 | } 71 | 72 | for i in (0..self.log_n).rev() { 73 | if self.parent[i][u] != self.parent[i][v] { 74 | u = self.parent[i][u]; 75 | v = self.parent[i][v]; 76 | } 77 | } 78 | self.parent[0][u] 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /rust/number_theory/mod_inverse.rs: -------------------------------------------------------------------------------- 1 | // Extended euclidean algorithm 2 | fn gex(a: i64, b: i64, x: &mut i64, y: &mut i64) -> i64 { 3 | if a == 0 { 4 | *x = 0; 5 | *y = 1; 6 | return b; 7 | } 8 | 9 | let mut x1 = 0; 10 | let mut y1 = 0; 11 | let g = gex(b % a, a, &mut x1, &mut y1); 12 | *x = y1 - (b / a) * x1; 13 | *y = x1; 14 | g 15 | } 16 | 17 | // Returns the mod inverse when a & m are co-prime, 18 | // panics otherwise 19 | fn inv(a: i64, m: i64) -> i64 { 20 | let mut x: i64 = 0; 21 | let mut y: i64 = 0; 22 | let g = gex(a, m, &mut x, &mut y); 23 | assert!(g == 1); 24 | (x % m + m) % m 25 | } 26 | 27 | // x^y mod m 28 | fn power(x: i64, y: i64, m: i64) -> i64 { 29 | if y == 0 { 30 | return 1; 31 | } 32 | 33 | let mut p = power(x, y >> 1, m) % m; 34 | p = p * p % m; 35 | if y % 2 == 1 { 36 | (x * p) % m 37 | } else { 38 | p 39 | } 40 | } -------------------------------------------------------------------------------- /rust/number_theory/sieve.rs: -------------------------------------------------------------------------------- 1 | // Sieve that runs in O(n). 2 | // Returns a list of smallest prime factors 3 | // for each i <= n and 4 | // and a lost of all primes <= n 5 | fn sieve(n: i32) -> (Vec, Vec) { 6 | let mut lp: Vec = (0..n+1).map(|_| 0).collect(); 7 | let mut prime: Vec = Vec::with_capacity(n as usize + 1); 8 | for i in 2..n as usize + 1 { 9 | if lp[i] == 0 { 10 | lp[i] = i as i32; 11 | prime.push(i as i32); 12 | } 13 | for j in &prime { 14 | if *j > lp[i as usize] || i as i32 * j > n { 15 | break; 16 | } 17 | lp[i * *j as usize] = *j; 18 | } 19 | } 20 | return (prime, lp); 21 | } 22 | -------------------------------------------------------------------------------- /rust/strings/longest-palindromic-substring-manacher.rs: -------------------------------------------------------------------------------- 1 | /** 2 | Manacher's algorithm for finding the longest palindromic substring. Returns two vectors: 3 |
    4 |
  1. max_odd: let x = max_odd[i]. This means that s[i - x] == s[i + x] and longest odd length palindrome centered at i is of length 2 * x + 1.
  2. 5 |
  3. max_even: let x = max_even[i]. This means that s[i - x - 1] == s[i + x] and longest even length palindrome centered at i is of length 2 * x + 2.
  4. 6 |
7 | NOTE: -1 in max_even[i] means that there is no even length palindrome centered at i. 8 | */ 9 | fn manachers(s: &Vec) -> (Vec, Vec) { 10 | let n = s.len(); 11 | let mut max_odd = vec![0; n]; 12 | let mut max_even = vec![0; n]; 13 | 14 | let mut l = 0; 15 | let mut r: i32 = -1; 16 | for i in 0..n as i32 { 17 | let mut k = match i as i32 > r { 18 | true => 1, 19 | false => min(max_odd[(l + r - i) as usize], (r - i) as usize), 20 | } as i32; 21 | while i - k >= 0 && i + k < n as i32 && s[(i - k) as usize] == s[(i + k) as usize] { 22 | k += 1; 23 | } 24 | k -= 1; 25 | max_odd[i as usize] = k as usize; 26 | if i + k > r { 27 | l = i - k; 28 | r = i + k; 29 | } 30 | } 31 | 32 | let mut l = 0; 33 | let mut r: i32 = -1; 34 | for i in 0..n as i32 { 35 | let mut k = match i > r { 36 | true => 0, 37 | false => min(max_even[(l + r - i + 1) as usize] as i32, r - i + 1), 38 | }; 39 | while i - k - 1 >= 0 && i + k < n as i32 && s[(i - k - 1) as usize] == s[(i + k) as usize] { 40 | k += 1; 41 | } 42 | k -= 1; 43 | max_even[i as usize] = k; 44 | if i + k > r { 45 | l = i - k - 1; 46 | r = i + k; 47 | } 48 | } 49 | 50 | (max_odd, max_even) 51 | } -------------------------------------------------------------------------------- /rust/template.rs: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Arjan Singh Bal 3 | "Everything in this world is magic, except to the magician" 4 | */ 5 | 6 | #[allow(unused_imports)] 7 | use std::str::FromStr; 8 | use std::io::{BufWriter, stdin, stdout, Write, Stdout}; 9 | 10 | #[derive(Default)] 11 | struct Scanner { 12 | buffer: Vec 13 | } 14 | 15 | impl Scanner { 16 | fn next(&mut self) -> T { 17 | loop { 18 | if let Some(token) = self.buffer.pop() { 19 | return token.parse().ok().expect("Failed parse"); 20 | } 21 | let mut input = String::new(); 22 | stdin().read_line(&mut input).expect("Failed read"); 23 | self.buffer = input.split_whitespace().rev().map(String::from).collect(); 24 | } 25 | } 26 | } 27 | 28 | fn main() { 29 | let mut scan = Scanner::default(); 30 | let mut out = &mut BufWriter::new(stdout()); 31 | let t = scan.next(); 32 | for _ in 0..t { 33 | solve(&mut scan, &mut out); 34 | } 35 | } 36 | 37 | fn solve(scan: &mut Scanner, out: &mut BufWriter) { 38 | 39 | } 40 | -------------------------------------------------------------------------------- /rust/utils/merge_sorted_vectors.rs: -------------------------------------------------------------------------------- 1 | fn merge_sorted(v1: &Vec, v2: &Vec) -> Vec { 2 | let mut res: Vec = Vec::with_capacity(v1.len() + v2.len()); 3 | let mut it1 = v1.iter().peekable(); 4 | let mut it2 = v2.iter().peekable(); 5 | 6 | while it1.peek() != None && it2.peek() != None { 7 | if it1.peek().unwrap() < it2.peek().unwrap() { 8 | res.push(*it1.next().unwrap()); 9 | } else { 10 | res.push(*it2.next().unwrap()); 11 | } 12 | } 13 | 14 | res.extend(it1); 15 | res.extend(it2); 16 | return res; 17 | } 18 | --------------------------------------------------------------------------------