├── 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