├── 2D Compressed Fenwick.cpp ├── 2D Fenwick with functional lib.cpp ├── 2D LIS segment tree complete array.cpp ├── Articulation points.cpp ├── Basic string addition:subtraction.cpp ├── Binary trie using static array.cpp ├── Bridges.cpp ├── Bulding Cartesian tree in O(N).cpp ├── Closest Points Nlog(N).cpp ├── Date:Time Python sample.py ├── Decart tree with data reference.cpp ├── Dijkstra + MinHeap(manual:not library).cpp ├── Dynamic median.cpp ├── Fast ternary search.cpp ├── Fibonacci Matrix.cpp ├── Huffman Encoding.cpp ├── Implicit segment tree.cpp ├── Johnson's all shortest paths algorithm.cpp ├── Karatsuba multiplication (O(N^1.58)).cpp ├── Kruskal MST.cpp ├── LCA with binary lifting.cpp ├── Linear Atkin sieve.cpp ├── Linear sieve.cpp ├── MINSTACK.cpp ├── MO's algorithm (sum queries).cpp ├── Manhattan 2D farthest points.cpp ├── Maximum Sum Subarray.cpp ├── Miller-Rabin Primaility test.cpp ├── Order-statistic tree (set).cpp ├── Original Decart tree.cpp ├── Persistent segment tree (Kth element query).cpp ├── Persistent segment tree array implementation.cpp ├── Quadtree 2D querying.cpp ├── Quicksort hack halyavin.cpp ├── README.md ├── Range comparison using hashes.cpp ├── Rope(builtin decart tree).cpp ├── Simple Trie.cpp ├── Simple decart tree (treap).cpp ├── Smallest cyclic shift (Nlog^2(N)).cpp ├── Triangle counting in graphs.cpp ├── Z + Prefix + KMP.cpp ├── fast I:O.cpp ├── mods and muls.txt ├── trie class (implement).cpp └── unordered_set hack.cpp /2D Compressed Fenwick.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 04/20/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | // 2D Longest increasing sequence problem 10 | // Solution with 2D-Fenwick trees with grid compression 11 | // O(N*log^2(N)) solution 12 | 13 | #pragma GCC optimize("-0g") 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | const int MAX = 100005; 24 | 25 | int N, Nx, Ny; 26 | int x[MAX], y[MAX]; 27 | int dp[MAX]; 28 | vector gridValues[MAX]; 29 | vector compressedFenwick[MAX]; 30 | 31 | void update(vector &fenwick, int position, int treeSize, int value) { 32 | for ( ; position <= treeSize; position += (position & -position)) { 33 | fenwick[position] = max(fenwick[position], value); 34 | } 35 | } 36 | int get(vector &fenwick, int position) { 37 | int s = 0; 38 | for ( ; position > 0; position -= (position & -position)) { 39 | s = max(s, fenwick[position]); 40 | } 41 | return s; 42 | } 43 | 44 | template 45 | void fastInput(T &N) { 46 | char ch; 47 | int sign = 1; 48 | N = 0; 49 | while ((ch = getchar_unlocked()) && ch == ' ') {}; 50 | if (ch == '-') sign = -1; 51 | else if (isdigit(ch)) N = ch - '0'; 52 | while ((ch = getchar_unlocked()) && isdigit(ch)) { 53 | N = (N << 1) + (N << 3) + ch - '0'; 54 | } 55 | if (sign == -1) N = ~N + 1; 56 | } 57 | 58 | int main() { 59 | //scanf("%d", &N); 60 | fastInput(N); 61 | //for (int i = 1; i <= N; i ++) scanf("%d%d", &x[i], &y[i]); 62 | for (int i = 1; i <= N; i ++) { 63 | fastInput(x[i]); 64 | fastInput(y[i]); 65 | } 66 | vector values = vector (x + 1, x + N + 1); 67 | sort(values.begin(), values.end()); 68 | values.erase(unique(values.begin(), values.end()), values.end()); 69 | for (int i = 1; i <= N; i ++) { 70 | x[i] = (int)(lower_bound(values.begin(), values.end(), x[i]) - values.begin()) + 1; 71 | } 72 | Nx = (int)values.size(); 73 | values = vector (y + 1, y + N + 1); 74 | sort(values.begin(), values.end()); 75 | values.erase(unique(values.begin(), values.end()), values.end()); 76 | for (int i = 1; i <= N; i ++) { 77 | y[i] = (int)(lower_bound(values.begin(), values.end(), y[i]) - values.begin()) + 1; 78 | } 79 | Ny = (int)values.size(); 80 | 81 | for (int i = 1; i <= N; i ++) { 82 | for (int j = x[i] - 1; j > 0; j -= (j & -j)) { 83 | gridValues[j].push_back(y[i]); 84 | } 85 | for (int j = x[i]; j <= Nx; j += (j & -j)) { 86 | gridValues[j].push_back(y[i]); 87 | } 88 | } 89 | for (int i = 1; i <= Nx; i ++) { 90 | gridValues[i].push_back(N); 91 | sort(gridValues[i].begin(), gridValues[i].end()); 92 | gridValues[i].erase(unique(gridValues[i].begin(), gridValues[i].end()), gridValues[i].end()); 93 | compressedFenwick[i].resize((int)gridValues[i].size() + 1, 0); 94 | } 95 | int result = 0; 96 | for (int i = 1; i <= N; i ++) { 97 | dp[i] = 1; 98 | for (int j = x[i] - 1; j > 0; j -= (j & -j)) { 99 | int currentY = (int)(lower_bound(gridValues[j].begin(), gridValues[j].end(), y[i]) - gridValues[j].begin()) + 1; 100 | dp[i] = max(dp[i], get(compressedFenwick[j], currentY - 1) + 1); 101 | } 102 | for (int j = x[i]; j <= Nx; j += (j & -j)) { 103 | int currentY = (int)(lower_bound(gridValues[j].begin(), gridValues[j].end(), y[i]) - gridValues[j].begin()) + 1; 104 | update(compressedFenwick[j], currentY, (int)compressedFenwick[j].size(), dp[i]); 105 | } 106 | result = max(result, dp[i]); 107 | } 108 | 109 | cout << result << endl; 110 | 111 | return 0; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /2D Fenwick with functional lib.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 01/23/18. 6 | // Copyright © 2017 Mahmud. All rights reserved. 7 | // 8 | 9 | /// log^2(N) per update 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | int tests; 17 | int N; 18 | char type[3]; 19 | 20 | template 21 | void fastInput(T &N) { 22 | char ch; 23 | int sign = 1; 24 | N = 0; 25 | while ((ch = getchar_unlocked()) && ch == ' ') {}; 26 | if (ch == '-') sign = -1; 27 | else if (isdigit(ch)) N = ch - '0'; 28 | while ((ch = getchar_unlocked()) && isdigit(ch)) { 29 | N = (N << 1) + (N << 3) + ch - '0'; 30 | } 31 | if (sign == -1) N = ~N + 1; 32 | } 33 | 34 | int main() { 35 | function update = [](int **ftree, int x, int y, int value){ 36 | for (int i = x; i <= N; i += (i & -i)) { 37 | for (int j = y; j <= N; j += (j & -j)) { 38 | ftree[i][j] += value; 39 | } 40 | } 41 | }; 42 | function getSum = [](int ** ftree, int x, int y) { 43 | int sum = 0; 44 | for (int i = x; i > 0; i -= (i & -i)) { 45 | for (int j = y; j > 0; j -= (j & -j)) { 46 | sum += ftree[i][j]; 47 | } 48 | } 49 | return sum; 50 | }; 51 | 52 | function print = [](ostream &os, int N) { 53 | os << N; 54 | os << '\n'; 55 | }; 56 | 57 | fastInput(tests); 58 | while (tests --) { 59 | fastInput(N); 60 | ostream out(nullptr); 61 | int **ftree = (int**)calloc(N + 1, sizeof(int)); 62 | for (int i = 0; i <= N; i ++) ftree[i] = (int*)calloc(N + 1, sizeof(int)); 63 | 64 | while (scanf("%s", type)) { 65 | if (type[0] == 'E') break; // end 66 | if (type[1] == 'E') { // set 67 | int x, y, value; 68 | fastInput(x); ++x; 69 | fastInput(y); ++y; 70 | fastInput(value); 71 | int oldValue = getSum(ftree, x, y) - getSum(ftree, x - 1, y) 72 | - getSum(ftree, x, y - 1) + getSum(ftree, x - 1, y - 1); 73 | update(ftree, x, y, -oldValue); 74 | update(ftree, x, y, value); 75 | } else { // query 76 | int x1, y1, x2, y2; 77 | fastInput(x1); ++x1; 78 | fastInput(y1); ++y1; 79 | fastInput(x2); ++x2; 80 | fastInput(y2); ++y2; 81 | print(std::cout, getSum(ftree,x2, y2) - getSum(ftree, x1 - 1, y2) 82 | - getSum(ftree, x2, y1 - 1) + getSum(ftree, x1 - 1, y1 - 1)); 83 | } 84 | } 85 | putchar_unlocked('\n'); 86 | } 87 | 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /2D LIS segment tree complete array.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 04/18/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #pragma GCC optimize("-0g") 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int MAX = 100005; 21 | 22 | int values[MAX * 75] = {-1}; 23 | int leftChildID[MAX * 75]; 24 | int rightChildID[MAX * 75]; 25 | int offset = 0; 26 | 27 | int N, Nx, Ny; 28 | int x[MAX], y[MAX]; 29 | int roots[MAX]; 30 | int dp[MAX]; 31 | 32 | void update(int rootID, int low, int high, int position, int value) { 33 | if (values[low] == -1) return; 34 | if (low == high) { 35 | values[rootID] = value; 36 | return; 37 | } 38 | int middle = (low + high) >> 1; 39 | if (position <= middle) { 40 | if (leftChildID[rootID] == 0) { 41 | leftChildID[rootID] = ++offset; 42 | values[offset] = 0; 43 | } 44 | update(leftChildID[rootID], low, middle, position, value); 45 | } 46 | else { 47 | if (rightChildID[rootID] == 0) { 48 | rightChildID[rootID] = ++offset; 49 | values[offset] = 0; 50 | } 51 | update(rightChildID[rootID], middle + 1, high, position, value); 52 | } 53 | values[rootID] = max(values[leftChildID[rootID]], values[rightChildID[rootID]]); 54 | } 55 | int get(int rootID, int low, int high, int l, int r) { 56 | if (values[rootID] == -1) return 0; 57 | if (low > r || high < l) return 0; 58 | if (low >= l && high <= r) return values[rootID]; 59 | int middle = (low + high) >> 1; 60 | int q1 = get(leftChildID[rootID], low, middle, l, r); 61 | int q2 = get(rightChildID[rootID], middle + 1, high, l, r); 62 | return q1 > q2 ? q1 : q2; 63 | //return max(get(pool[root.leftChildID], low, middle, l, r), 64 | // get(pool[root.rightChildID], middle + 1, high, l, r)); 65 | } 66 | void outerUpdate(int position, int innerPosition, int value) { 67 | for ( ; position <= Nx; position += (position & -position)) { 68 | if (values[roots[position]] == -1) { 69 | roots[position] = ++offset; 70 | values[roots[position]] = 0; 71 | } 72 | update(roots[position], 1, Ny, innerPosition, value); 73 | } 74 | } 75 | int outerGet(int position, int innerL, int innerR) { 76 | int s = 0; 77 | for ( ; position > 0; position -= (position & -position)) { 78 | int current = get(roots[position], 1, Ny, innerL, innerR); 79 | if (current > s) s = current; 80 | } 81 | return s; 82 | } 83 | 84 | template 85 | void fastInput(T &N) { 86 | char ch; 87 | int sign = 1; 88 | N = 0; 89 | while ((ch = getchar_unlocked()) && ch == ' ') {}; 90 | if (ch == '-') sign = -1; 91 | else if (isdigit(ch)) N = ch - '0'; 92 | while ((ch = getchar_unlocked()) && isdigit(ch)) { 93 | N = (N << 1) + (N << 3) + ch - '0'; 94 | } 95 | if (sign == -1) N = ~N + 1; 96 | } 97 | /**** FAST IO ****/ 98 | inline int readChar(); 99 | template inline T readInt(); 100 | template inline void writeInt( T x, char end = 0 ); 101 | inline void writeChar( int x ); 102 | inline void writeWord( const char *s ); 103 | 104 | /** Read */ 105 | 106 | static const int buf_size = 4096; 107 | 108 | inline int getChar() { 109 | static char buf[buf_size]; 110 | static int len = 0, pos = 0; 111 | if (pos == len) 112 | pos = 0, len = fread(buf, 1, buf_size, stdin); 113 | if (pos == len) 114 | return -1; 115 | return buf[pos++]; 116 | } 117 | 118 | inline int readChar() { 119 | int c = getChar(); 120 | while (c <= 32) 121 | c = getChar(); 122 | return c; 123 | } 124 | 125 | template 126 | inline T readInt() { 127 | int s = 1, c = readChar(); 128 | T x = 0; 129 | if (c == '-') 130 | s = -1, c = getChar(); 131 | while ('0' <= c && c <= '9') 132 | x = x * 10 + c - '0', c = getChar(); 133 | return s == 1 ? x : -x; 134 | } 135 | 136 | /** Write */ 137 | 138 | static int write_pos = 0; 139 | static char write_buf[buf_size]; 140 | 141 | inline void writeChar( int x ) { 142 | if (write_pos == buf_size) 143 | fwrite(write_buf, 1, buf_size, stdout), write_pos = 0; 144 | write_buf[write_pos++] = x; 145 | } 146 | 147 | template 148 | inline void writeInt( T x, char end ) { 149 | if (x < 0) 150 | writeChar('-'), x = -x; 151 | 152 | char s[24]; 153 | int n = 0; 154 | while (x || !n) 155 | s[n++] = '0' + x % 10, x /= 10; 156 | while (n--) 157 | writeChar(s[n]); 158 | if (end) 159 | writeChar(end); 160 | } 161 | 162 | inline void writeWord( const char *s ) { 163 | while (*s) 164 | writeChar(*s++); 165 | } 166 | 167 | struct Flusher { 168 | ~Flusher() { 169 | if (write_pos) 170 | fwrite(write_buf, 1, write_pos, stdout), write_pos = 0; 171 | } 172 | } flusher; 173 | 174 | int main() { 175 | //scanf("%d", &N); 176 | N = readInt(); 177 | //fastInput(N); 178 | //for (int i = 1; i <= N; i ++) scanf("%d%d", &x[i], &y[i]); 179 | for (int i = 1; i <= N; i ++) { 180 | //fastInput(x[i]); 181 | //fastInput(y[i]); 182 | x[i] = readInt(); 183 | y[i] = readInt(); 184 | } 185 | vector values = vector (x + 1, x + N + 1); 186 | sort(values.begin(), values.end()); 187 | values.erase(unique(values.begin(), values.end()), values.end()); 188 | for (int i = 1; i <= N; i ++) { 189 | x[i] = (int)(lower_bound(values.begin(), values.end(), x[i]) - values.begin()) + 1; 190 | } 191 | Nx = (int)values.size(); 192 | values = vector (y + 1, y + N + 1); 193 | sort(values.begin(), values.end()); 194 | values.erase(unique(values.begin(), values.end()), values.end()); 195 | for (int i = 1; i <= N; i ++) { 196 | y[i] = (int)(lower_bound(values.begin(), values.end(), y[i]) - values.begin()) + 1; 197 | } 198 | Ny = (int)values.size(); 199 | 200 | int result = 0; 201 | for (int i = 1; i <= N; i ++) { 202 | dp[i] = outerGet(x[i] - 1, 1, y[i] - 1) + 1; 203 | //cout << i << " --> " << x[i] << " " << y[i] << endl; 204 | //cout << i << " " << dp[i] << endl; 205 | if (dp[i] > result) result = dp[i]; 206 | outerUpdate(x[i], y[i], dp[i]); 207 | } 208 | cout << result << endl; 209 | 210 | return 0; 211 | } 212 | -------------------------------------------------------------------------------- /Articulation points.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 03/27/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | // O(N + M) calculation of articulation points 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | const int MAX = 100005; 19 | 20 | int N, M; 21 | vector> graph; 22 | 23 | int timer = 0; 24 | int visited[MAX]; 25 | int timeIN[MAX], fup[MAX]; 26 | 27 | int critical[MAX]; 28 | vector articulation; 29 | 30 | void dfs(int node, int parent = -1) { 31 | visited[node] = 1; 32 | timeIN[node] = fup[node] = timer ++; 33 | int children = 0; 34 | for (int i : graph[node]) { 35 | if (i == parent) continue; 36 | if (visited[i]) { 37 | fup[node] = min(fup[node], timeIN[i]); 38 | } 39 | else { 40 | dfs(i, node); 41 | fup[node] = min(fup[node], fup[i]); 42 | children ++; 43 | if (parent != -1 && fup[i] >= timeIN[node]) { 44 | critical[node] = 1; 45 | } 46 | } 47 | } 48 | if (parent == -1 && children > 1) critical[node] = 1; 49 | } 50 | 51 | int main() { 52 | while (scanf("%d%d", &N, &M)) { 53 | if (N == 0 && M == 0) break; 54 | graph.resize(N + 1); 55 | for (int i = 1; i <= N; i ++) graph[i].clear(); 56 | for (int i = 1; i <= N; i ++) visited[i] = 0; 57 | for (int i = 1; i <= N; i ++) critical[i] = 0; 58 | for (int i = 0; i < M; i ++) { 59 | int u, v; 60 | scanf("%d%d", &u, &v); 61 | graph[u].push_back(v); 62 | graph[v].push_back(u); 63 | } 64 | for (int i = 1; i <= N; i ++) { 65 | if (!visited[i]) dfs(i); 66 | } 67 | // for (int i = 1; i <= N; i ++) { 68 | // if (critical[i]) articulation.push_back(i); 69 | // } 70 | int result = 0; 71 | for (int i = 1; i <= N; i ++) { 72 | if (critical[i]) result ++; 73 | } 74 | printf("%d\n", result); 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Basic string addition:subtraction.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 6/04/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | const int MAX = 10001; 17 | 18 | string add(string a, string b) { 19 | string c = ""; 20 | int i = (int)a.size() - 1; 21 | int j = (int)b.size() - 1; 22 | int q = 0; 23 | while (i >= 0 || j >= 0) { 24 | int sum = q; 25 | if (i >= 0) sum += a[i] - '0'; 26 | if (j >= 0) sum += b[j] - '0'; 27 | if (sum > 9) { 28 | sum -= 10; 29 | q = 1; 30 | } 31 | else { 32 | q = 0; 33 | } 34 | i --; 35 | j --; 36 | c += (char)(sum + '0'); 37 | } 38 | if (q > 0) { 39 | c += (char)('1'); 40 | } 41 | reverse(c.begin(), c.end()); 42 | return c; 43 | } 44 | string subtract(string a, string b) { 45 | string c = ""; 46 | int i = (int)a.size() - 1; 47 | int j = (int)b.size() - 1; 48 | int r = 0; 49 | while (i >= 0) { 50 | int difference = a[i] - '0' - r; 51 | if (j >= 0) { 52 | difference -= b[j] - '0'; 53 | } 54 | if (difference < 0) { 55 | difference += 10; 56 | r = 1; 57 | } 58 | else { 59 | r = 0; 60 | } 61 | i --; 62 | j --; 63 | c += (char)(difference + '0'); 64 | } 65 | while ((int)c.size() > 1 && c.back() == '0') { 66 | c.pop_back(); 67 | } 68 | reverse(c.begin(), c.end()); 69 | return c; 70 | } 71 | int compare(string a, string b) { 72 | int l1 = (int)a.size(); 73 | int l2 = (int)b.size(); 74 | if (l1 > l2) return 1; 75 | if (l1 < l2) return -1; 76 | for (int i = 0; i < l1; i ++) { 77 | if (a[i] > b[i]) return 1; 78 | if (a[i] < b[i]) return -1; 79 | } 80 | return 0; 81 | } 82 | string divide(string a, int b) { 83 | string c = ""; 84 | int q = 0; 85 | for (int i = 0; i < (int)a.size(); i ++) { 86 | q = 10 * q + a[i] - '0'; 87 | int r = q / b; 88 | q %= b; 89 | if (r > 0 || !c.empty()) { 90 | c += (char)(r + '0'); 91 | } 92 | } 93 | if (c.empty()) c = ""; 94 | return c; 95 | } 96 | 97 | int main() { 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /Binary trie using static array.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 03/10/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | // reference problem: 10 | // https://www.spoj.com/problems/XORX/ 11 | 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | const int S = 1 << 18; 18 | const int MAX_BIT = 30; 19 | 20 | struct node{ 21 | int value; 22 | int leftChildID; 23 | int rightChildID; 24 | node() { 25 | 26 | } 27 | node(int v, int l, int r): 28 | value(v), leftChildID(l), rightChildID(r) { 29 | 30 | } 31 | }; 32 | 33 | node pool[S]; 34 | int offset = 0; 35 | 36 | int allocate(int value) { 37 | pool[++offset].value = value; 38 | pool[offset].leftChildID = -1; 39 | pool[offset].rightChildID = -1; 40 | return offset; 41 | } 42 | void add(int value) { 43 | int id = 0; 44 | for (int i = MAX_BIT; i >= 0; i --) { 45 | int bit = (value >> i) & 1; 46 | if (!bit) { 47 | if (pool[id].leftChildID == -1) { 48 | pool[id].leftChildID = allocate(0); 49 | } 50 | id = pool[id].leftChildID; 51 | } else { 52 | if (pool[id].rightChildID == -1) { 53 | pool[id].rightChildID = allocate(0); 54 | } 55 | id = pool[id].rightChildID; 56 | } 57 | pool[id].value = 1; 58 | } 59 | } 60 | int getMatch(int x) { 61 | int id = 0; 62 | int result = 0; 63 | for (int i = MAX_BIT; i >= 0; i --) { 64 | if (pool[id].value == 0) { 65 | break; 66 | } 67 | int bit = (x >> i) & 1; 68 | if (!bit) { 69 | if (pool[id].rightChildID != -1) { 70 | result |= 1 << i; 71 | id = pool[id].rightChildID; 72 | } else { 73 | id = pool[id].leftChildID; 74 | } 75 | } else { 76 | if (pool[id].leftChildID != -1) { 77 | id = pool[id].leftChildID; 78 | } else { 79 | result |= 1 << i; 80 | id = pool[id].rightChildID; 81 | } 82 | } 83 | } 84 | return result; 85 | } 86 | 87 | int N, T, X; 88 | int data[S]; 89 | 90 | int main() { 91 | scanf("%d", &T); 92 | while (T --) { 93 | scanf("%d%d", &N, &X); 94 | for (int i = 1; i <= N; i ++) { 95 | scanf("%d", &data[i]); 96 | } for (int i = 0; i < S; i ++) { 97 | pool[i] = node(0, -1, -1); 98 | } 99 | pool[0].value = 1; 100 | offset = 0; 101 | add(0); 102 | int prefix = 0, bestResult = data[1]; 103 | for (int i = 1; i <= N; i ++) { 104 | prefix ^= data[i]; 105 | add(prefix); 106 | int current = prefix ^ getMatch(X ^ prefix); 107 | if ((X ^ current) > (X ^ bestResult)) { 108 | bestResult = current; 109 | } 110 | } 111 | printf("%d\n", bestResult); 112 | } 113 | 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /Bridges.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 03/26/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | // O(N + M) calculation of bridges in undirected graph 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int MAX = 705; 21 | 22 | int T, N, M; 23 | int timer; 24 | int visited[MAX], timeIN[MAX], fup[MAX]; 25 | vector> graph; 26 | vector> bridges; 27 | 28 | void dfs(int node, int parent = -1) { 29 | visited[node] = 1; 30 | fup[node] = timeIN[node] = ++timer; 31 | for (int i : graph[node]) { 32 | if (i == parent) continue; 33 | if (visited[i]) { 34 | fup[node] = min(fup[node], timeIN[i]); 35 | } 36 | else { 37 | dfs(i, node); 38 | fup[node] = min(fup[node], fup[i]); 39 | if (fup[i] > timeIN[node]) { 40 | bridges.push_back(make_pair(min(node, i), max(node, i))); 41 | } 42 | } 43 | } 44 | } 45 | 46 | int main() { 47 | scanf("%d", &T); 48 | for (int c = 0; c < T; c ++) { 49 | scanf("%d%d", &N, &M); 50 | graph.resize(N + 1); 51 | for (int i = 1; i <= N; i ++) graph[i].clear(); 52 | for (int i = 0; i < M; i ++) { 53 | int u, v; 54 | scanf("%d%d", &u, &v); 55 | graph[u].push_back(v); 56 | graph[v].push_back(u); 57 | } 58 | timer = 0; 59 | bridges.clear(); 60 | for (int i = 1; i <= N; i ++) visited[i] = 0; 61 | for (int i = 1; i <= N; i ++) { 62 | if (!visited[i]) dfs(i); 63 | } 64 | sort(bridges.begin(), bridges.end()); 65 | bridges.erase(unique(bridges.begin(), bridges.end()), bridges.end()); 66 | 67 | printf("Caso #%d\n", c + 1); 68 | if (bridges.empty()) puts("Sin bloqueos"); 69 | else { 70 | printf("%d\n", (int)bridges.size()); 71 | for (auto i : bridges) printf("%d %d\n", i.first, i.second); 72 | } 73 | } 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /Bulding Cartesian tree in O(N).cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 02/18/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | using namespace std; 12 | 13 | const int MAX = 100005; 14 | 15 | int N; 16 | int data[MAX]; 17 | int label[MAX], leftChild[MAX], rightChild[MAX], parent[MAX]; 18 | 19 | int main() { 20 | cin >> N; 21 | for (int i = 1; i <= N; i ++) cin >> data[i]; 22 | 23 | int root = 1; 24 | leftChild[1] = 0; 25 | rightChild[1] = 0; 26 | label[1] = data[1]; 27 | 28 | for (int i = 2; i <= N; i ++) { 29 | int last = i - 1; 30 | label[i] = data[i]; 31 | rightChild[i] = 0; 32 | while (label[last] > data[i] && last != root) { 33 | last = parent[last]; 34 | } 35 | if (label[last] > data[i]) { 36 | parent[root] = i; 37 | leftChild[i] = root; 38 | root = i; 39 | } 40 | else if(rightChild[last] == 0) { 41 | rightChild[last] = i; 42 | parent[i] = last; 43 | leftChild[i] = 0; 44 | } 45 | else { 46 | parent[rightChild[last]] = i; 47 | leftChild[i] = rightChild[last]; 48 | rightChild[last] = i; 49 | parent[i] = last; 50 | } 51 | } 52 | cout << "root = " << root << endl; 53 | for (int i = 1; i <= N; i ++) { 54 | cout << i << " " << label[i] << " " << leftChild[i] << " " << rightChild[i] << ", and parent = " << parent[i] << endl; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Closest Points Nlog(N).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int me = 50025; 6 | 7 | struct point{ 8 | double x, y; 9 | int pos; 10 | point() {} 11 | point(double x, double y, int pos) : x(x), y(y), pos(pos) {} 12 | bool operator <(const point other) const{ 13 | return x < other.x 14 | || (x == other.x && y < other.y); 15 | } 16 | double dis(const point other){ 17 | return sqrt(1. * (x - other.x) * (x - other.x) + 1. * (y - other.y) * (y - other.y)); 18 | } 19 | }; 20 | 21 | int n, p1, p2; 22 | point p[me]; 23 | double ans = 1.e30; 24 | 25 | void get(int low, int high){ 26 | if(low >= high) 27 | return; 28 | if(low + 1 == high){ 29 | double d = p[low].dis(p[low + 1]); 30 | if(d < ans){ 31 | ans = d; 32 | p1 = p[low].pos; 33 | p2 = p[low + 1].pos; 34 | } 35 | return; 36 | } 37 | int mid = (low + high + 1) >> 1; 38 | get(low, mid); 39 | get(mid + 1, high); 40 | 41 | vector v; 42 | for(int i = low; i <= high; i ++) 43 | if(fabs(p[i].x - p[mid].x) <= ans || fabs(p[i].y - p[mid].x) <= ans) 44 | v.push_back(p[i]); 45 | for(int i = 0; i < v.size(); i ++) 46 | for(int j = 0; j < i; j ++) 47 | if(v[i].dis(v[j]) < ans){ 48 | ans = v[i].dis(v[j]); 49 | p1 = v[i].pos; 50 | p2 = v[j].pos; 51 | } 52 | } 53 | 54 | int main() 55 | { 56 | //ios_base::sync_with_stdio(0); 57 | //cin.tie(0); 58 | 59 | scanf("%d", &n); 60 | for(int i = 0; i < n; i ++){ 61 | scanf("%lf%lf", &p[i].x, &p[i].y); 62 | p[i].pos = i; 63 | } 64 | sort(p, p + n); 65 | get(0, n - 1); 66 | 67 | if(p1 > p2) 68 | swap(p1, p2); 69 | printf("%d %d %.6f\n", p1, p2, ans); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Date:Time Python sample.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | sundays = 0 4 | date = datetime.datetime(1901, 1, 1) 5 | 6 | while True: 7 | if date.day == 1 and date.weekday() == 6: 8 | sundays += 1 9 | if date == datetime.datetime(2000, 12, 31): 10 | break 11 | date += datetime.timedelta(days=1) 12 | print(sundays) 13 | -------------------------------------------------------------------------------- /Decart tree with data reference.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 12/10/17. 6 | // Copyright © 2017 Mahmud. All rights reserved. 7 | // 8 | 9 | 10 | /* 11 | Reference problem: 12 | https://www.spoj.com/problems/CARDFLIP/ 13 | 14 | Except some solution based on sqrt decomposition, it seems the problem has only 15 | the following solution which is based on decart trees. 16 | Please, carefully read what kind of operations is requested in the statement. 17 | */ 18 | 19 | /* 20 | O((N + Q) * log(N)) solution using Decart trees 21 | The queries of type 1 and 2 are be handled in standard Decart tree implementations. 22 | And in order to work with queries of type 3, 23 | we can use the following approach: 24 | --> Keep a parent link from each tree node. 25 | --> Since we use pointers for each nodes, we can track any element using its pointer node... (<3) 26 | --> If we are required to reverse any range, parent links will not be affected. 27 | --> Update links when you do Merge/Split operations. 28 | --> When type-3 query come, first do update update operations until you reach root node. 29 | --> Finally, traverse the path to root and count sizes of skipped left subtrees till the root node. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | using namespace std; 41 | 42 | const int MAX = 100005; 43 | const int _INFINITY = 1 << 30; 44 | 45 | struct node{ 46 | int value; 47 | int priority; 48 | int subtree_value; 49 | int subtreeSize; 50 | bool reversed; 51 | node* leftChild; 52 | node* rightChild; 53 | node* parent; 54 | int state; // 0 --> left child, 1 --> right child 55 | }; 56 | 57 | typedef node* tree; 58 | 59 | int getValue(tree t){ 60 | return t? t->subtree_value : _INFINITY; 61 | } 62 | int getSize(tree t){ 63 | return t? t->subtreeSize : 0; 64 | } 65 | void update(tree t){ 66 | if(t) { 67 | t->subtree_value = min(getValue(t->leftChild), 68 | min(t->value, getValue(t->rightChild))); 69 | t->subtreeSize = getSize(t->leftChild) + 1 + getSize(t->rightChild); 70 | if (t->leftChild) { 71 | t->leftChild->parent = t; 72 | t->leftChild->state = 0; 73 | } 74 | if (t->rightChild) { 75 | t->rightChild->parent = t; 76 | t->rightChild->state = 1; 77 | } 78 | } 79 | } 80 | 81 | void push(tree t){ 82 | if(t && t->reversed){ 83 | update(t); 84 | t->reversed = 0; 85 | swap(t->leftChild, t->rightChild); 86 | if(t->leftChild) { 87 | t->leftChild->reversed ^= 1; 88 | t->leftChild->state ^= 1; 89 | } 90 | if(t->rightChild) { 91 | t->rightChild->reversed ^= 1; 92 | t->rightChild->state ^= 1; 93 | } 94 | } 95 | } 96 | void Split(tree t, tree &l, tree &r, int pos, int add = 0){ 97 | if(!t) 98 | return void(l = r = NULL); 99 | push(t); 100 | int cur_pos = getSize(t->leftChild) + add; 101 | if(cur_pos + 1 <= pos) { 102 | Split(t->rightChild, t->rightChild, r, pos, cur_pos + 1); 103 | l = t; 104 | } 105 | else { 106 | Split(t->leftChild, l, t->leftChild, pos, add); 107 | r = t; 108 | } 109 | update(t); 110 | } 111 | void Merge(tree &t, tree l, tree r){ 112 | push(l); 113 | push(r); 114 | if(!l || !r) 115 | t = l? l : r; 116 | else if(l->priority > r->priority) { 117 | Merge(l->rightChild, l->rightChild, r); 118 | t = l; 119 | } 120 | else { 121 | Merge(r->leftChild, l, r->leftChild); 122 | t = r; 123 | } 124 | update(t); 125 | } 126 | tree Initialize(int key){ 127 | tree p = (tree)malloc(sizeof(node)); 128 | p->value = key; 129 | p->priority = rand(); 130 | p->subtree_value = key; 131 | p->subtreeSize = 1; 132 | p->reversed = 0; 133 | p->leftChild = NULL; 134 | p->rightChild = NULL; 135 | p->parent = NULL; 136 | p->state = 0; 137 | return p; 138 | } 139 | void Insert(tree &t, tree item, int position){ 140 | tree l1, r1; 141 | Split(t, l1, r1, position - 1); 142 | Merge(l1, l1, item); 143 | Merge(t, l1, r1); 144 | } 145 | void Insert(tree &t, int position, int key){ 146 | tree p = Initialize(key); 147 | Insert(t, p, position); 148 | } 149 | void Erase(tree &t, int position){ 150 | tree l1, r1; 151 | Split(t, l1, r1, position - 1); 152 | tree l2, r2; 153 | Split(r1, l2, r2, 1); 154 | Merge(t, l1, r2); 155 | } 156 | void Reverse(tree &t, int l, int r){ 157 | tree l1, r1; 158 | Split(t, l1, r1, l - 1); 159 | tree l2, r2; 160 | Split(r1, l2, r2, r - l + 1); 161 | l2->reversed ^= 1; 162 | Merge(r1, l2, r2); 163 | Merge(t, l1, r1); 164 | } 165 | int Query(tree &t, int l, int r){ 166 | tree l1, r1; 167 | Split(t, l1, r1, l - 1); 168 | tree l2, r2; 169 | Split(r1, l2, r2, r - l + 1); 170 | int ans = getValue(l2); 171 | Merge(r1, l2, r2); 172 | Merge(t, l1, r1); 173 | return ans; 174 | } 175 | bool Find(tree t, int key){ 176 | push(t); 177 | if(!t) 178 | return false; 179 | if(t->value == key) 180 | return true; 181 | if(t->value > key) 182 | return Find(t->leftChild, key); 183 | return Find(t->rightChild, key); 184 | } 185 | int Get_index(tree &t, int key, int add = 0){ 186 | push(t); 187 | if(t->value == key && getValue(t->leftChild) > key) 188 | return getSize(t->leftChild) + add + 1; 189 | else if(getValue(t->leftChild) <= key) 190 | return Get_index(t->leftChild, key, add); 191 | return Get_index(t->rightChild, key, add + getSize(t->leftChild) + 1); 192 | } 193 | int Kth_element(tree t, int k){ 194 | push(t); 195 | if(getSize(t->leftChild) + 1 == k) 196 | return t->value; 197 | if(getSize(t->leftChild) + 1 > k) 198 | return Kth_element(t->leftChild, k); 199 | return Kth_element(t->rightChild, k - getSize(t->leftChild) - 1); 200 | } 201 | void fixPath(tree &t) { 202 | if (!t) return; 203 | fixPath(t->parent); 204 | push(t); 205 | } 206 | int calculatePosition(tree &t, int lastState) { 207 | int skipped = 0; 208 | if (lastState == 1) skipped = 1 + getSize(t->leftChild); 209 | if (t->parent == NULL) return skipped; 210 | else return skipped + calculatePosition(t->parent, t->state); 211 | } 212 | int positionOfElement(tree &t) { 213 | fixPath(t); 214 | return calculatePosition(t, +1); 215 | } 216 | void assignParents(tree &t) { 217 | if (!t) return; 218 | if (t->leftChild) { 219 | t->leftChild->parent = t; 220 | t->leftChild->state = 0; 221 | } 222 | if (t->rightChild) { 223 | t->rightChild->parent = t; 224 | t->rightChild->state = 1; 225 | } 226 | assignParents(t->leftChild); 227 | assignParents(t->rightChild); 228 | } 229 | void Print(tree t){ 230 | if(!t) 231 | return; 232 | push(t); 233 | Print(t->leftChild); 234 | cout << t->value << " "; 235 | Print(t->rightChild); 236 | } 237 | 238 | int N, Q; 239 | int type, x, l, r; 240 | tree t = NULL; 241 | tree nodes[MAX]; 242 | 243 | int main() { 244 | srand(unsigned(time(NULL))); 245 | 246 | scanf("%d%d", &N, &Q); 247 | for(int i = 1; i <= N; i ++){ 248 | nodes[i] = Initialize(i); 249 | Insert(t, nodes[i], i); 250 | } 251 | assignParents(t); 252 | while (Q --){ 253 | //Print(t); cout << endl; 254 | scanf("%d", &type); 255 | if (type == 1) { 256 | scanf("%d%d", &l, &r); 257 | Reverse(t, l, r); 258 | } 259 | else if(type == 2) { 260 | scanf("%d", &x); 261 | printf("%d\n", Kth_element(t, x)); 262 | } 263 | else { 264 | scanf("%d", &x); 265 | printf("%d\n", positionOfElement(nodes[x])); 266 | } 267 | } 268 | 269 | return 0; 270 | } 271 | -------------------------------------------------------------------------------- /Dijkstra + MinHeap(manual:not library).cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 10/11/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | const int MAX_NODE_COUNT = 1 << 17; 18 | typedef vector>> graph; 19 | 20 | 21 | class item { 22 | int node; 23 | int d; // distance 24 | 25 | public: 26 | item() { 27 | 28 | } 29 | item(int _n, int _d) { 30 | node = _n; 31 | d = _d; 32 | } 33 | int getNodeID() { 34 | return node; 35 | } 36 | int getDistance() { 37 | return d; 38 | } 39 | void setNodeID(int _n) { 40 | node = _n; 41 | } 42 | void setDistance(int _d) { 43 | d = _d; 44 | } 45 | bool operator < (const item other) const { 46 | if (d != other.d) { 47 | return d < other.d; 48 | } else { 49 | return node < other.node; 50 | } 51 | } 52 | bool operator < (const int key) const { 53 | return d < key; 54 | } 55 | bool operator == (const item other) const { 56 | return node == other.node && d == other.d; 57 | } 58 | bool operator <= (const item other) const { 59 | return make_pair(d, node) <= make_pair(other.d, other.node); 60 | } 61 | bool operator >= (const item other) const { 62 | return make_pair(d, node) >= make_pair(other.d, other.node); 63 | } 64 | bool operator > (const item other) const { 65 | if (d != other.d) { 66 | return d > other.d; 67 | } else { 68 | return node > other.node; 69 | } 70 | } 71 | }; 72 | 73 | class MinHeap { 74 | const int MAX_HEAP_SIZE = 1 << 18; 75 | 76 | int heapSize; 77 | vector data; 78 | 79 | int parent(int node) { 80 | return node >> 1; 81 | } 82 | int leftChild(int node) { 83 | return node << 1; 84 | } 85 | int rightChild(int node) { 86 | return node << 1 | 1; 87 | } 88 | void heapify(int node) { 89 | int position = node; 90 | if (leftChild(node) <= heapSize && data[leftChild(node)] < data[position]) { 91 | position = leftChild(node); 92 | } if (rightChild(node) <= heapSize && data[rightChild(node)] < data[position]) { 93 | position = rightChild(node); 94 | } 95 | if (position != node) { 96 | swap(data[position], data[node]); 97 | heapify(position); 98 | } 99 | } 100 | void siftUp(int node) { 101 | while (node > 1 && data[parent(node)] > data[node]) { 102 | swap(data[parent(node)], data[node]); 103 | node = parent(node); 104 | } 105 | } 106 | 107 | public: 108 | MinHeap() { 109 | heapSize = 0; 110 | data.resize(MAX_HEAP_SIZE); 111 | } 112 | int getSize() { 113 | return heapSize; 114 | } 115 | item heapMin() { 116 | return data[1]; 117 | } 118 | int heapMinValue() { 119 | return data[1].getDistance(); 120 | } 121 | int heapMinID() { 122 | return data[1].getNodeID(); 123 | } 124 | void buildHeap() { 125 | for (int i = (getSize() >> 1); i >= 1; i --) { 126 | heapify(i); 127 | } 128 | } 129 | void extractMin() { 130 | data[1] = data[heapSize --]; 131 | heapify(1); 132 | } 133 | void heapIncreaseKey(int node, int key) { 134 | if (data[node].getDistance() >= key) { 135 | return; 136 | } 137 | data[node].setDistance(key); 138 | siftUp(node); 139 | } 140 | void heapInsert(int id, int key) { 141 | ++heapSize; 142 | data[heapSize].setNodeID(id); 143 | data[heapSize].setDistance(-(1 << 30)); 144 | heapIncreaseKey(heapSize, key); 145 | } 146 | }; 147 | 148 | //#include 149 | //#include 150 | // 151 | //bool test() { 152 | // srand(unsigned(time(NULL))); 153 | // MinHeap h; 154 | // multiset s; 155 | // for (int i = 0; i < 50000; i ++) { 156 | // int x = rand() * rand() % 123456; 157 | // s.insert(x); 158 | // h.heapInsert(x); 159 | // } 160 | // for (int i = 0; i < 10000; i ++) { 161 | // int type, a; 162 | // type = rand() % 3; 163 | // if (type == 0) { 164 | // a = rand() * rand() % 123456; 165 | // h.heapInsert(a); 166 | // s.insert(a); 167 | // } else if (type == 1) { 168 | // h.extractMin(); 169 | // s.erase(s.begin()); 170 | // } else { 171 | // int a = h.heapMin(); 172 | // int b = *s.begin(); 173 | // if (a != b) { 174 | // return false; 175 | // } 176 | // } 177 | // } 178 | // return true; 179 | //} 180 | 181 | 182 | 183 | 184 | int N, M; 185 | int source, sink; 186 | graph G; 187 | vector> edgeList; 188 | 189 | vector bfs(int source, graph G) { 190 | int nodes = (int)G.size(); 191 | vector distances(nodes, nodes + 1); 192 | queue Q; 193 | Q.push(source); 194 | distances[source] = 0; 195 | while (!Q.empty()) { 196 | int current = Q.front(); 197 | Q.pop(); 198 | for (auto neighbor: G[current]) { 199 | if (distances[neighbor.first] > distances[current] + 1) { 200 | distances[neighbor.first] = distances[current] + 1; 201 | Q.push(neighbor.first); 202 | } 203 | } 204 | } 205 | return distances; 206 | } 207 | 208 | int main() { 209 | // cout << test() << endl; 210 | 211 | //freopen("input.txt", "r", stdin); 212 | //freopen("output.txt", "w", stdout); 213 | 214 | scanf("%d%d", &N, &M); 215 | scanf("%d%d", &source, &sink); 216 | 217 | G.resize(N); 218 | for (int i = 0; i < M; i ++) { 219 | int u, v, l; 220 | scanf("%d%d%d", &u, &v, &l); 221 | G[u].push_back(make_pair(v, l)); 222 | // if undirected, add the the backward edge. 223 | //G[v].push_back(make_pair(u, l)); 224 | 225 | // edgeList.push_back(make_pair(u, l)); 226 | } 227 | // vector minMoves = bfs(source, G); 228 | // G.clear(); 229 | // G.resize(N); 230 | // for (auto edge: edgeList) { 231 | // int from = edge.first; 232 | // int to = edge.second; 233 | // if (minMoves[from] & 1) { 234 | // G[from].push_back(make_pair(to, 2)); 235 | // } else { 236 | // G[from].push_back(make_pair(to, 1)); 237 | // } 238 | // } 239 | vector distances(N, 1 << 30); 240 | distances[source] = 0; 241 | MinHeap h; 242 | h.heapInsert(source, 0); 243 | while (h.getSize() > 0) { 244 | int top = h.heapMinID(); 245 | int d = h.heapMinValue(); 246 | h.extractMin(); 247 | if (d > distances[top]) { 248 | continue; 249 | } 250 | for (auto neighbor: G[top]) { 251 | int to = neighbor.first; 252 | int weight = neighbor.second; 253 | if (distances[to] > distances[top] + weight) { 254 | distances[to] = distances[top] + weight; 255 | h.heapInsert(to, distances[to]); 256 | } 257 | } 258 | } 259 | printf("%d", distances[sink]); 260 | 261 | return 0; 262 | } 263 | -------------------------------------------------------------------------------- /Dynamic median.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | int t; 21 | int x; 22 | multiset small, big; 23 | 24 | void fix(){ 25 | while((int)small.size() - 1 > (int)big.size()){ 26 | int x = *(--small.end()); 27 | big.insert(x); 28 | small.erase(small.find(x)); 29 | } 30 | while((int)small.size() < (int)big.size()){ 31 | int x = *(big.begin()); 32 | small.insert(x); 33 | big.erase(big.find(x)); 34 | } 35 | while(!small.empty() && !big.empty() && *(--small.end()) > *(big.begin())){ 36 | int x = *(--small.end()); 37 | int y = *(big.begin()); 38 | small.erase(small.find(x)); 39 | big.insert(x); 40 | big.erase(big.find(y)); 41 | small.insert(y); 42 | } 43 | } 44 | 45 | int main(int argc, const char * argv[]) { 46 | scanf("%d", &t); 47 | 48 | while(t --){ 49 | small.clear(); 50 | big.clear(); 51 | while(scanf("%d", &x)){ 52 | if(x == 0) 53 | break; 54 | if(x > 0){ 55 | small.insert(x); 56 | fix(); 57 | } 58 | else{ 59 | x = *(--small.end()); 60 | printf("%d\n", x); 61 | small.erase(small.find(x)); 62 | fix(); 63 | } 64 | } 65 | if(t > 0) 66 | printf("\n"); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Fast ternary search.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 04/30/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /* 10 | Fast ternary search 11 | Tested on the following problem: http://www.spoj.com/problems/KOPC12A/ 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | const int MAX = 10005; 26 | 27 | int T, N; 28 | int height[MAX], cost[MAX]; 29 | 30 | int main() { 31 | scanf("%d", &T); 32 | while (T --) { 33 | scanf("%d", &N); 34 | for (int i = 1; i <= N; i ++) scanf("%d", &height[i]); 35 | for (int i = 1; i <= N; i ++) scanf("%d", &cost[i]); 36 | 37 | auto f = [](int h) { 38 | long long sum = 0; 39 | for (int i = 1; i <= N; i ++) { 40 | sum += 1LL * cost[i] * abs(height[i] - h); 41 | } 42 | return sum; 43 | }; 44 | int low = 0, high = 10000; 45 | while (low < high) { 46 | int middle = (low + high) >> 1; 47 | if (f(middle) < f(middle + 1)) { 48 | high = middle; 49 | } 50 | else { 51 | low = middle + 1; 52 | } 53 | } 54 | cout << min(f(low), f(low + 1)) << endl; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Fibonacci Matrix.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 04/04/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /// Calculating Fibonacci(N) in O(log(N)) by matrix exponentiation 10 | /// Note, here fib(0) = fib(1) = 1 11 | 12 | #include 13 | 14 | using namespace std; 15 | 16 | const int mod = 1000000007; 17 | 18 | struct matrix{ 19 | int a[2][2]; 20 | matrix() { 21 | for(int i = 0; i < 2; i ++) 22 | for(int j = 0; j < 2; j ++) 23 | a[i][j] = 0; 24 | } 25 | }; 26 | 27 | matrix mul(matrix a, matrix b){ 28 | matrix c; 29 | for(int i = 0; i < 2; i ++) 30 | for(int j = 0; j < 2; j ++) 31 | c.a[i][j] = 0; 32 | for(int i = 0; i < 2; i ++) 33 | for(int j = 0; j < 2; j ++) 34 | for(int k = 0; k < 2; k ++) 35 | c.a[i][j] = (c.a[i][j] + 1LL * a.a[i][k] * b.a[k][j] % mod) % mod; 36 | return c; 37 | } 38 | matrix power(matrix a, long long b){ 39 | if(b == 1) 40 | return a; 41 | if(b & 1) 42 | return mul(power(a, b - 1), a); 43 | matrix half = power(a, b >> 1); 44 | return mul(half, half); 45 | } 46 | 47 | int T; 48 | long long N; 49 | matrix F; 50 | 51 | int main() { 52 | 53 | cin >> T; 54 | while (T --) { 55 | cin >> N; 56 | if (N < 2) { 57 | cout << 1 << endl; 58 | continue; 59 | } 60 | F.a[0][0] = 1; 61 | F.a[0][1] = 1; 62 | F.a[1][0] = 1; 63 | F.a[1][1] = 0; 64 | F = power(F, N); 65 | 66 | cout << F.a[0][0] << endl; 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Huffman Encoding.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 01/31/19. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | using namespace std; 21 | 22 | void read(string& text) { 23 | freopen("input.txt", "r", stdin); 24 | text = ""; 25 | string s; 26 | while (cin >> s) { 27 | if (cin.eof()) 28 | break; 29 | for (char &ch: s) 30 | ch = tolower(ch); 31 | text += s; 32 | } 33 | } 34 | 35 | int main(int argc, const char * argv[]) { 36 | string text = "this is an example for huffman encoding"; 37 | 38 | read(text); 39 | 40 | map counters; 41 | for_each(begin(text), end(text), [&](char ch) { 42 | counters[ch] ++; 43 | }); 44 | for (auto i: counters) { 45 | cout << "weight of " << i.first << " is " << i.second << endl; 46 | } 47 | 48 | 49 | //priority_queue, greater > Q; 50 | priority_queue >, vector >>, 51 | greater >>> Q; 52 | // I know it is ugly ^. 53 | 54 | for (auto i: counters) { 55 | Q.push(make_pair(i.second, vector(1, i.first))); 56 | } 57 | map identifiers; 58 | while (int(Q.size()) > 1) { 59 | auto itemSet1 = Q.top(); 60 | Q.pop(); 61 | auto itemSet2 = Q.top(); 62 | Q.pop(); 63 | for_each(begin(itemSet1.second), end(itemSet1.second), [&](char ch) { 64 | identifiers[ch] = '0' + identifiers[ch]; 65 | }); 66 | for_each(begin(itemSet2.second), end(itemSet2.second), [&](char ch) { 67 | identifiers[ch] = '1' + identifiers[ch]; 68 | }); 69 | int weight = itemSet1.first + itemSet2.first; 70 | vector merged = itemSet1.second; 71 | for (auto ch: itemSet2.second) 72 | merged.push_back(ch); 73 | Q.push(make_pair(weight, merged)); 74 | } 75 | 76 | cout << endl; 77 | 78 | vector> result; 79 | for (auto item: identifiers) 80 | result.push_back(make_pair(item.first, item.second)); 81 | sort(result.begin(), result.end(), [](pair a, pair b) { 82 | string s1 = a.second; 83 | string s2 = b.second; 84 | if (s1.length() != s2.length()) 85 | return s1.length() < s2.length(); 86 | for (int i = 0; i < s1.length(); i ++) { 87 | if (s1[i] != s2[i]) 88 | return s1[i] < s2[i]; 89 | } 90 | return false; 91 | }); 92 | for_each(begin(result), end(result), [&](pair item) { 93 | cout << item.second << " " << item.first << endl; 94 | }); 95 | 96 | cout << endl; 97 | cout << endl; 98 | 99 | int huffmanTotal = 0; 100 | for (auto item: counters) 101 | huffmanTotal += item.second * identifiers[item.first].length(); 102 | double v = text.length() * log2(int(counters.size())); 103 | 104 | cout << "length of the initial text in bits: " << text.length() * log2(int(counters.size())) << endl; 105 | cout << "length via Huffman encoding in bits: " << huffmanTotal << endl; 106 | cout << "the number of the saved bits: " << text.length() * 8 - huffmanTotal << endl; 107 | cout << "the gain in the size in percentages is: " << 100. * (v - huffmanTotal) / v << endl; 108 | cout << endl; 109 | 110 | 111 | double entropySource = 0.; 112 | for (auto item: counters) { 113 | entropySource += -1. * item.second / text.length() * log2(1. * item.second / text.length()); 114 | } 115 | cout << "entropy of the source is: " << entropySource * int(text.length()) << endl; 116 | cout << "average length for huffman encoding is: " << 1. * huffmanTotal / text.length() << endl; 117 | cout << endl; 118 | 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /Implicit segment tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int me = 100025; 21 | const int sz = 1200000000; 22 | 23 | struct node{ 24 | int sum; 25 | node *l, *r; 26 | 27 | node() {} 28 | }; 29 | typedef node * pnode; 30 | 31 | int get(pnode &t){ 32 | return t ? t->sum : 0; 33 | } 34 | pnode Init(int sum){ 35 | pnode p = (pnode)malloc(sizeof(node)); 36 | p->sum = sum; 37 | p->l = NULL; 38 | p->r = NULL; 39 | return p; 40 | } 41 | void add(int low, int high, pnode &root, int pos, int value){ 42 | if(!root) 43 | root = Init(0); 44 | if(low == high){ 45 | root->sum += value; 46 | return; 47 | } 48 | int mid = (low + high) >> 1; 49 | if(pos <= mid) 50 | add(low, mid, root->l, pos, value); 51 | else add(mid + 1, high, root->r, pos, value); 52 | root->sum = get(root->l) + get(root->r); 53 | } 54 | int get(int low, int high, pnode &root, int l, int r){ 55 | if(low > r || high < l) 56 | return 0; 57 | if(!root) 58 | return 0; 59 | if(low >= l && high <= r) 60 | return root->sum; 61 | int mid = (low + high) >> 1; 62 | return get(low, mid, root->l, l, r) 63 | + get(mid + 1, high, root->r, l, r); 64 | } 65 | int Kth_element(int low, int high, pnode &root, int k){ 66 | if(low == high) 67 | return low; 68 | int mid = (low + high) >> 1; 69 | int on_left = get(root->l); 70 | if(on_left >= k) 71 | return Kth_element(low, mid, root->l, k); 72 | else return Kth_element(mid + 1, high, root-> r, k - on_left); 73 | } 74 | 75 | int n, q, type, x; 76 | pnode root; 77 | 78 | int main() { 79 | //ios_base::sync_with_stdio(0); 80 | //cin.tie(0); 81 | 82 | root = Init(0); 83 | 84 | scanf("%d%d", &n, &q); 85 | for(int i = 1; i <= n; i ++){ 86 | scanf("%d", &x); 87 | add(1, sz, root, x, 1); 88 | } 89 | while(q --){ 90 | scanf("%d%d", &type, &x); 91 | if(type == 1){ 92 | int cnt = get(1, sz, root, 1, x); 93 | add(1, sz, root, cnt + x, 1); 94 | } 95 | else if(type == 2){ 96 | printf("%d\n", get(1, sz, root, 1, x)); 97 | } 98 | else{ 99 | if(get(root) < x) 100 | printf("invalid\n"); 101 | else printf("%d\n", Kth_element(1, sz, root, x)); 102 | } 103 | } 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /Johnson's all shortest paths algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /// Jonhson's Algorithm 4 | /// All pair's shortest path problem 5 | /// Complexity: O(V^2 * log(V) + V * E) 6 | 7 | using namespace std; 8 | 9 | #define mp make_pair 10 | #define pb push_back 11 | #define y1 lalalalalala 12 | #define index lalalalalalala 13 | #define show(a, i) cout << "a[" << i << "] = " << a[i] << endl; 14 | #define all(x) x.begin(), x.end() 15 | #define vi vector 16 | #define ll long long 17 | 18 | const int INF = 1e9 + 1; 19 | 20 | int getint() 21 | { 22 | char ch; 23 | int neg = 1; 24 | int val = 0; 25 | 26 | while(ch = getchar()) 27 | { 28 | if(ch == '-') neg = -1; 29 | else if(ch > 57 || ch < 48) break; 30 | else val = 10 * val + ch - 48; 31 | } 32 | val = val * neg; 33 | return val; 34 | } 35 | 36 | const int cs = 1e5 + 1; 37 | 38 | struct edge 39 | { 40 | int to; 41 | int w; 42 | edge () { 43 | 44 | } 45 | }; 46 | 47 | struct c_edge 48 | { 49 | int from; 50 | int to; 51 | int w; 52 | c_edge () { 53 | 54 | } 55 | }; 56 | 57 | struct node 58 | { 59 | int d; 60 | int vertex; 61 | }; 62 | 63 | struct cmp 64 | { 65 | bool operator()(node A, node B) 66 | { 67 | return A.d < B.d; 68 | } 69 | }; 70 | 71 | vector< vector >v; 72 | vectorV; 73 | vector< vi >dis; 74 | vi h, used; 75 | priority_queue, cmp>Q; 76 | int n, m; 77 | 78 | void relax(c_edge x) 79 | { 80 | if(h[x.from] != INT_MAX) 81 | h[x.to] = min(h[x.to], h[x.from] + x.w); 82 | } 83 | 84 | bool Bellman_Ford() 85 | { 86 | for(int i = 1 ; i <= n ; i ++) 87 | V.pb({n + 1, i, 0}); 88 | 89 | for(int i = 1 ; i <= n ; i ++) 90 | h[i] = INT_MAX; 91 | 92 | h[n + 1] = 0; 93 | 94 | for(int i = 1 ; i <= n ; i ++) 95 | for(auto j : V) 96 | relax(j); 97 | 98 | for(auto j : V) 99 | if(h[j.to] > h[j.from] + j.w) 100 | return true; 101 | return false; 102 | } 103 | 104 | void init_Dijkstra(int vertex) 105 | { 106 | while(!Q.empty()) 107 | Q.pop(); 108 | dis[vertex].resize(n + 1, INT_MAX); 109 | } 110 | 111 | void Dijkstra(int vertex) 112 | { 113 | init_Dijkstra(vertex); 114 | 115 | dis[vertex][vertex] = 0; 116 | Q.push({0, vertex}); 117 | 118 | while(!Q.empty()) 119 | { 120 | node current = Q.top(); 121 | Q.pop(); 122 | 123 | for(auto i : v[current.vertex]) 124 | { 125 | if(dis[vertex][i.to] > current.d + i.w) 126 | { 127 | dis[vertex][i.to] = current.d + i.w; 128 | Q.push({dis[vertex][i.to], i.to}); 129 | } 130 | } 131 | } 132 | } 133 | 134 | int main() 135 | { 136 | ios_base::sync_with_stdio(false); 137 | cin.tie(false); 138 | 139 | cin >> n >> m; 140 | 141 | V.resize(m); 142 | h.resize(n + 2); 143 | dis.resize(n + 2); 144 | v.resize(n + 1); 145 | 146 | for(int i = 0 ; i < m ; i ++) 147 | cin >> V[i].from >> V[i].to >> V[i].w; 148 | 149 | if( Bellman_Ford() == true) 150 | { 151 | cout << "negative cycle" << endl; 152 | return 0; 153 | } 154 | 155 | for(auto i : V) 156 | { 157 | if(i.from == n + 1) 158 | continue; 159 | v[i.from].pb({i.to, i.w + h[i.from] - h[i.to]}); 160 | } 161 | 162 | for(int i = 1 ; i <= n ; i ++) 163 | Dijkstra(i); 164 | 165 | for(int i = 1 ; i <= n ; i ++) 166 | for(int j = 1 ; j <= n ; j ++) 167 | dis[i][j] = dis[i][j] + h[j] - h[i]; 168 | cout << endl; 169 | for(int i = 1 ; i <= n ; i ++) 170 | { 171 | for(int j = 1 ; j <= n ; j ++) 172 | cout << dis[i][j] << " "; 173 | cout << endl; 174 | } 175 | ///cerr << "Elapsed time: " << 1.0 * clock() / CLOCKS_PER_SEC << " sec" << endl; 176 | return 0; 177 | } 178 | -------------------------------------------------------------------------------- /Karatsuba multiplication (O(N^1.58)).cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 10/28/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /* 10 | Karatsuba multiplication in O(N^(log2(3))) ~ N^1.58 11 | Please, refer to https://en.wikipedia.org/wiki/Karatsuba_algorithm 12 | to see the inner mechanism in the algorithm. 13 | Some for loops and operations can be replaced with builtin functions for speedup. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | typedef string number; 23 | 24 | bool isZero(number &a) { 25 | for (auto ch: a) { 26 | if (ch != '0') { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | number add(number a, number b) { // addition of two numbers in linear time 33 | string sum = ""; 34 | int i = (int)a.size() - 1; 35 | int j = (int)b.size() - 1; 36 | int r = 0; 37 | while (i >= 0 || j >= 0) { 38 | int state = r; 39 | if (i >= 0) state += a[i] - '0'; 40 | if (j >= 0) state += b[j] - '0'; 41 | if (state > 9) { 42 | state -= 10; 43 | r = 1; 44 | } else { 45 | r = 0; 46 | } 47 | i --; 48 | j --; 49 | sum += (char)(state + '0'); 50 | } 51 | if (r > 0) { 52 | sum += (char)(r + '0'); 53 | } 54 | while ((int)sum.size() > 1 && sum.back() == '0') { 55 | sum.pop_back(); 56 | } 57 | reverse(sum.begin(), sum.end()); 58 | return sum; 59 | } 60 | string subtract(number a, number b) { // assuming a >= b, subtraction in linear time 61 | string difference = ""; 62 | int i = (int)a.size() - 1; 63 | int j = (int)b.size() - 1; 64 | int r = 0; 65 | while (i >= 0) { 66 | int state = a[i] - '0' - r; 67 | if (j >= 0) { 68 | state -= b[j] - '0'; 69 | } 70 | if (state < 0) { 71 | state += 10; 72 | r = 1; 73 | } else { 74 | r = 0; 75 | } 76 | i --; 77 | j --; 78 | difference += (char)(state + '0'); 79 | } 80 | while ((int)difference.size() > 1 && difference.back() == '0') { 81 | difference.pop_back(); 82 | } 83 | reverse(difference.begin(), difference.end()); 84 | return difference; 85 | } 86 | void split(number &a, number &l, number &r) { 87 | int length = (int)a.size(); 88 | int half = length >> 1; 89 | l = a.substr(0, half); 90 | r = a.substr(half); 91 | } 92 | void normalize(number &a, number &b) { // making the lengths equal to 2's power 93 | int la = (int)a.size(); 94 | int lb = (int)b.size(); 95 | int to = -1; 96 | for (int i = 0; ; i ++) { 97 | if ((1 << i) >= la && (1 << i) >= lb) { 98 | to = (1 << i); 99 | break; 100 | } 101 | } 102 | if (la < to) { 103 | reverse(a.begin(), a.end()); 104 | while (la < to) { 105 | a += '0'; 106 | la ++; 107 | } 108 | reverse(a.begin(), a.end()); 109 | } 110 | if (lb < to) { 111 | reverse(b.begin(), b.end()); 112 | while (lb < to) { 113 | b += '0'; 114 | lb ++; 115 | } 116 | reverse(b.begin(), b.end()); 117 | } 118 | 119 | } 120 | void insertTrailingZeros(number &a, int z) { 121 | for (int i = 0; i < z; i ++) { 122 | a += '0'; 123 | } 124 | } 125 | string defaultMultiplier(number a, number b) { 126 | int aValue = stoi(a); 127 | int bValue = stoi(b); 128 | return to_string(aValue * bValue); 129 | } 130 | number karatsuba(number a, number b) { 131 | if ((int)a.size() < 3) { // if small string lengths achieved, use integer multiplication 132 | return defaultMultiplier(a, b); 133 | } 134 | // if (isZero(a) || isZero(b)) { 135 | // return "0"; 136 | // } 137 | normalize(a, b); 138 | string leftA, rightA; 139 | string leftB, rightB; 140 | split(a, leftA, rightA); 141 | split(b, leftB, rightB); 142 | string p1 = karatsuba(leftA, leftB); 143 | string p2 = karatsuba(rightA, rightB); 144 | string aSum = add(leftA, rightA); 145 | string bSum = add(leftB, rightB); 146 | string p3 = karatsuba(aSum, bSum); 147 | string p4 = subtract(subtract(p3, p1), p2); 148 | insertTrailingZeros(p1, (int)a.size()); 149 | insertTrailingZeros(p4, (int)a.size() >> 1); 150 | return add(p1, add(p2, p4)); 151 | } 152 | number multiply(number a, number b) { 153 | // considering that this code assumes only positive numbers, 154 | // you can handle negative numbers as well (even big decimals). 155 | return karatsuba(a, b); 156 | } 157 | 158 | int main(int argc, const char * argv[]) { 159 | string a, b; 160 | cin >> a >> b; 161 | cout << multiply(a, b) << endl; 162 | 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /Kruskal MST.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 04/30/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | const int MAX = 100005; 17 | 18 | typedef pair> edge; 19 | 20 | int N, M; 21 | vector edges; 22 | 23 | int parent[MAX], size[MAX]; 24 | 25 | int Find(int x) { 26 | return x == parent[x] ? x : parent[x] = Find(parent[x]); 27 | } 28 | bool Union(int x, int y) { 29 | int root1 = Find(x); 30 | int root2 = Find(y); 31 | if (root1 == root2) return false; 32 | if (size[root1] > size[root2]) swap(root1, root2); 33 | if (size[root1] == size[root2]) size[root2] += size[root1]; 34 | parent[root1] = root2; 35 | return true; 36 | } 37 | 38 | int main() { 39 | cin >> N >> M; 40 | for (int i = 0; i < M; i ++) { 41 | int u, v, l; 42 | cin >> u >> v >> l; 43 | edges.push_back(make_pair(l, make_pair(u, v))); 44 | } 45 | sort(edges.begin(), edges.end()); 46 | 47 | for (int i = 1; i <= N; i ++) { 48 | parent[i] = i; 49 | size[i] = 1; 50 | } 51 | int mst = 0; 52 | for (auto i : edges) { 53 | int x = i.second.first; 54 | int y = i.second.second; 55 | if (Union(x, y)) mst += i.first; 56 | } 57 | cout << mst << endl; 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /LCA with binary lifting.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 01/02/19. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /* 10 | LCA implementation with binary lifting 11 | - O(N * log(N)) preprocessing 12 | - O(log(N)) per query to find the LCA of two given nodes 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int MAX_SIZE = 1 << 10; 21 | const int MAX_LEVELS = 10; 22 | 23 | int N, Q; 24 | vector> graph; 25 | 26 | int depth[MAX_SIZE]; 27 | int parents[MAX_SIZE][MAX_LEVELS]; 28 | 29 | void dfs(int node, int parent) { // dfs to assign depths in the tree 30 | parents[node][0] = parent; 31 | for (int i: graph[node]) { 32 | if (i != parent) { 33 | depth[i] = depth[node] + 1; 34 | dfs(i, node); 35 | } 36 | } 37 | } 38 | int lca(int u, int v) { 39 | if (depth[u] < depth[v]) { 40 | swap(u, v); 41 | } 42 | for (int i = MAX_LEVELS - 1; i >= 0; i --) { 43 | if (depth[u] >= depth[v] + (1 << i)) { 44 | u = parents[u][i]; 45 | } 46 | } 47 | if (u == v) { 48 | return u; 49 | } 50 | for (int i = MAX_LEVELS - 1; i >= 0; i --) { 51 | if (parents[u][i] != 0 && parents[u][i] != parents[v][i]) { 52 | u = parents[u][i]; 53 | v = parents[v][i]; 54 | } 55 | } 56 | return parents[u][0]; 57 | } 58 | 59 | int main(int argc, const char * argv[]) { 60 | cin >> N; 61 | graph.resize(N + 1); 62 | for (int i = 1; i < N; i ++) { 63 | int u, v; 64 | cin >> u >> v; 65 | graph[u].push_back(v); 66 | graph[v].push_back(u); 67 | } 68 | // preprocessing 69 | dfs(1, 0); 70 | for (int i = 1; i < MAX_LEVELS; i ++) { 71 | for (int j = 1; j <= N; j ++) { 72 | if (parents[j][i - 1] != 0) { 73 | parents[j][i] = parents[parents[j][i - 1]][i - 1]; 74 | } 75 | } 76 | } 77 | cin >> Q; 78 | for (int c = 0; c < Q; c ++) { 79 | int u, v; 80 | cin >> u >> v; 81 | cout << "Case " << c + 1 << ": "; 82 | cout << "LCA is: " << lca(u, v) << endl; 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /Linear Atkin sieve.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 12/24/17. 6 | // Copyright © 2017 Mahmud. All rights reserved. 7 | // 8 | 9 | /// Atkin's linear sieve algorithm 10 | /// reference: https://en.wikipedia.org/wiki/Sieve_of_Atkin 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int LIMIT = 1000000001; 21 | const int SQUARE_COUNT = 40005; 22 | const int WHEEL = 60; 23 | const int WHEEL_SIZE = 16; 24 | 25 | char prime[LIMIT]; 26 | int s[] = {1, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 49, 53, 59}; // generating wheel 27 | int Modulos1[] = {1, 13, 17, 29, 37, 41, 49, 53}; 28 | int Modulos2[] = {7, 19, 31, 43}; 29 | int Modulos3[] = {11, 23, 47, 59}; 30 | int activeModulos1[WHEEL]; 31 | int activeModulos2[WHEEL]; 32 | int activeModulos3[WHEEL]; 33 | int squares[SQUARE_COUNT]; // may need 34 | 35 | int main() { 36 | for (int i = 0; i < sizeof(Modulos1) / sizeof(int); i ++) activeModulos1[Modulos1[i]] = 1; 37 | for (int i = 0; i < sizeof(Modulos2) / sizeof(int); i ++) activeModulos2[Modulos2[i]] = 1; 38 | for (int i = 0; i < sizeof(Modulos2) / sizeof(int); i ++) activeModulos3[Modulos3[i]] = 1; 39 | 40 | //for (int i = 1; i < SQUARE_COUNT; i ++) squares[i] = i * i; 41 | //fill(prime, prime + LIMIT, 1); 42 | // for (int w = 0, N; w * WHEEL < LIMIT; w ++) { 43 | // for (int j = 0; j < WHEEL_SIZE && (N = w * WHEEL + s[j]) < LIMIT; j ++) { 44 | // prime[w * WHEEL + s[j]] = 0; 45 | // } 46 | // } 47 | cerr << "done in: " << 1.0 * clock() / CLOCKS_PER_SEC << endl; 48 | for (int x = 1, N, M = 4; M < LIMIT; x ++, M = 4 * x * x) { 49 | for (int y = 1; (N = M + y * y) < LIMIT; y += 2) { 50 | if (activeModulos1[N % WHEEL]) prime[N] ^= 1; 51 | } 52 | } 53 | cerr << "done in: " << 1.0 * clock() / CLOCKS_PER_SEC << endl; 54 | for (int x = 1, N, M = 3; M < LIMIT; x += 2, M = 3 * x * x) { 55 | for (int y = 2; (N = M + y * y) < LIMIT; y += 2) { 56 | if (activeModulos2[N % WHEEL]) prime[N] ^= 1; 57 | } 58 | } 59 | cerr << "done in: " << 1.0 * clock() / CLOCKS_PER_SEC << endl; 60 | for (int x = 2, N, M = 12; M - (x - 1) * (x - 1) < LIMIT; x ++, M = 3 * x * x) { 61 | for (int y = x - 1; y > 0 && (N = M - y * y) < LIMIT; y -= 2) { 62 | if (activeModulos3[N % WHEEL]) prime[N] ^= 1; 63 | } 64 | } 65 | cerr << "done in: " << 1.0 * clock() / CLOCKS_PER_SEC << endl; 66 | for (int w = 0, N; (w * WHEEL) * (w * WHEEL) < LIMIT; w ++) { 67 | for (int x = 0; x < WHEEL_SIZE; x ++) { 68 | N = WHEEL * w + s[x]; 69 | if (N < 7 || !prime[N]) continue; 70 | for (int c = N * N; c < LIMIT; c += N * N) prime[c] = 0; 71 | } 72 | } 73 | cerr << "done in: " << 1.0 * clock() / CLOCKS_PER_SEC << endl; 74 | return 0; 75 | int cnt = 3; 76 | cout << 2 << endl; 77 | cout << 3 << endl; 78 | cout << 5 << endl; 79 | for (int w = 0, N; w * WHEEL < LIMIT; w ++) { 80 | for (int j = 0; j < WHEEL_SIZE && (N = w * WHEEL + s[j]) < LIMIT; j ++) { 81 | if (prime[WHEEL * w + s[j]]) cnt ++; 82 | } 83 | } 84 | cout << "number of primes = " << cnt << endl; 85 | 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /Linear sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | //#include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | const int me = 1000025; 22 | const int sz = 21; 23 | 24 | int t, n, m, k, ps; 25 | int primes[me], lp[me], phi[me], depth[me], sum[sz][me]; 26 | 27 | int main(int argc, const char * argv[]) { 28 | //ios_base::sync_with_stdio(0); 29 | //cin.tie(0); 30 | 31 | for(int i = 2; i < me; i ++){ 32 | if(!lp[i]){ 33 | primes[++ps] = i; 34 | lp[i] = i; 35 | } 36 | for(int j = 1; j <= ps && primes[j] <= lp[i] && i * primes[j] < me; j ++) 37 | lp[i * primes[j]] = primes[j]; 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /MINSTACK.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 12/28/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /* 10 | Enhancing stack to support 11 | retrieval of minimum element in current stack in O(1). 12 | The idea is to keep the data value as a pair in stack, 13 | where the pair consists of the value of the element itself and 14 | the minimum value seen so far. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | using namespace std; 23 | 24 | int Q; 25 | int value; 26 | char type[10]; 27 | stack> minStack; 28 | 29 | int main(int argc, const char * argv[]) { 30 | scanf("%d", &Q); getchar(); 31 | while (Q --) { 32 | scanf("%s", type); 33 | if (type[1] == 'U') { // PUSH 34 | scanf("%d", &value); 35 | minStack.push(make_pair(value, minStack.empty() ? value: min(minStack.top().second, value))); 36 | } else if (type[1] == 'O') { // POP 37 | if (minStack.empty()) { 38 | puts("EMPTY"); 39 | } else { 40 | minStack.pop(); 41 | } 42 | } 43 | else { // MIN 44 | if (minStack.empty()) { 45 | puts("EMPTY"); 46 | } else { 47 | printf("%d\n", minStack.top().second); 48 | } 49 | } 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /MO's algorithm (sum queries).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | const long long me = 100025; 24 | const int BLOCK_SIZE = 325; 25 | 26 | struct query{ 27 | int l, r; 28 | int id; 29 | query() {} 30 | query(int l, int r, int id) : l(l), r(r), id(id) {} 31 | bool operator < (const query other) const{ 32 | if(l / BLOCK_SIZE != other.l / BLOCK_SIZE) 33 | return l / BLOCK_SIZE < other.l / BLOCK_SIZE; 34 | return r < other.r; 35 | } 36 | }; 37 | struct fenwick{ 38 | long long *ft; 39 | int sz; 40 | fenwick() {} 41 | fenwick(int size) : sz(size), ft(new long long [size + 1]) { 42 | fill(ft, ft + sz, 0); 43 | } 44 | void add(int pos, int value){ 45 | for( ; pos < sz; pos += (pos & -pos)) 46 | ft[pos] += value; 47 | } 48 | long long get(int pos){ 49 | long long sum = 0; 50 | for( ; pos > 0; pos -= (pos & -pos)) 51 | sum += ft[pos]; 52 | return sum; 53 | } 54 | long long get(int l, int r){ 55 | return get(r) - get(l - 1); 56 | } 57 | }; 58 | 59 | int n, m, k; 60 | long long sum; 61 | int a[me], lb[me], rb[me]; 62 | long long ans[me]; 63 | fenwick ft; 64 | vector values; 65 | vector q; 66 | 67 | void add(int w){ 68 | sum += ft.get(lb[w], rb[w]); 69 | ft.add(a[w], 1); 70 | } 71 | void remove(int w){ 72 | ft.add(a[w], -1); 73 | sum -= ft.get(lb[w], rb[w]); 74 | } 75 | 76 | /* 77 | 6 6 78 | 3 2 0 5 4 1 79 | 3 6 80 | 2 2 81 | 4 5 82 | 1 4 83 | 1 6 84 | 1 1 85 | */ 86 | 87 | int main() 88 | { 89 | ios_base::sync_with_stdio(0); 90 | cin.tie(0); 91 | 92 | scanf("%d%d", &n, &k); 93 | for(int i = 1; i <= n; i ++) 94 | scanf("%d", &a[i]); 95 | scanf("%d", &m); 96 | for(int i = 0; i < m; i ++){ 97 | int l, r; 98 | scanf("%d%d", &l, &r); 99 | if(l == r){ 100 | ans[i] = 0; 101 | } 102 | else{ 103 | q.push_back(query(l + 1, r + 1, i)); 104 | } 105 | } 106 | sort(q.begin(), q.end()); 107 | for(int i = 1; i <= n; i ++){ 108 | values.push_back(a[i]); 109 | } 110 | sort(values.begin(), values.end()); 111 | values.erase(unique(values.begin(), values.end()), values.end()); 112 | for(int i = 1; i <= n; i ++){ 113 | lb[i] = (int)(lower_bound(values.begin(), values.end(), a[i] - k) - values.begin()) + 1; 114 | rb[i] = (int)(upper_bound(values.begin(), values.end(), a[i] + k) - values.begin()); 115 | a[i] = (int)(lower_bound(values.begin(), values.end(), a[i]) - values.begin()) + 1; 116 | } 117 | ft = (fenwick)(me); 118 | int L = 1, R = 0; 119 | for(int i = 0; i < (int)q.size(); i ++){ 120 | while(L > q[i].l) 121 | add(-- L); 122 | while(L < q[i].l) 123 | remove(L ++); 124 | while(R < q[i].r) 125 | add(++R); 126 | while(R > q[i].r) 127 | remove(R --); 128 | ans[q[i].id] = sum; 129 | } 130 | for(int i = 0; i < m; i ++) 131 | printf("%lld\n", ans[i]); 132 | 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /Manhattan 2D farthest points.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Surely, the solution can be adapted to larger dimensions. 4 | 5 | using namespace std; 6 | 7 | const int me = 100025; 8 | 9 | struct point{ 10 | vector x; 11 | point() {} 12 | point(vector x) : x(x) {} 13 | 14 | bool operator ==(const point other) const{ 15 | return x == other.x; 16 | } 17 | bool operator <(const point other) const{ 18 | return x < other.x; 19 | } 20 | int dis(const point other){ 21 | int d = 0; 22 | for(int i = 0; i < x.size(); i ++) 23 | d += abs(x[i] - other.x[i]); 24 | return d; 25 | } 26 | }; 27 | 28 | int n, m, ans; 29 | point a[me]; 30 | set best; 31 | 32 | int main() 33 | { 34 | //ios_base::sync_with_stdio(0); 35 | //cin.tie(0); 36 | 37 | scanf("%d%d", &n, &m); 38 | for(int i = 0; i < n; i ++){ 39 | a[i].x.resize(m); 40 | for(int j = 0; j < m; j ++) 41 | scanf("%d", &a[i].x[j]); 42 | } 43 | for(int i = 0; i < (1 << m); i ++){ 44 | int far_d = 0, near_d = 0; 45 | int far_i = 0, near_i = 0; 46 | for(int j = 0; j < n; j ++){ 47 | int s = 0; 48 | for(int k = 0; k < m; k ++){ 49 | if(i & (1 << k)) 50 | s += a[j].x[k]; 51 | else s -= a[j].x[k]; 52 | } 53 | if(s > far_d){ 54 | far_d = s; 55 | far_i = j; 56 | } 57 | if(s < near_d){ 58 | near_d = s; 59 | near_i = j; 60 | } 61 | } 62 | best.insert(a[far_i]); 63 | best.insert(a[near_i]); 64 | } 65 | for(int i = 0; i < n; i ++) 66 | for(auto j : best) 67 | ans = max(ans, a[i].dis(j)); 68 | cout << ans << endl; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Maximum Sum Subarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define _INFINITY 1 << 30 7 | #define M 1000001 8 | 9 | 10 | /* 11 | Maximum Sum Subarray Problem 12 | O(N * log(N)) solution with divide & conquer 13 | */ 14 | 15 | using namespace std; 16 | 17 | int n, i, j, k; 18 | int a[M]; 19 | char ch; 20 | 21 | int FindMaxCrossingSubarray(int A[M], int low, int mid, int high) 22 | { 23 | int leftsum = -_INFINITY; 24 | int sum = 0; 25 | int maxleft, maxright; 26 | for(i = mid ; i >= low ; i --) 27 | { 28 | sum = sum + A[i]; 29 | if(sum > leftsum) 30 | { 31 | leftsum = sum; 32 | maxleft = i; 33 | } 34 | } 35 | int rightsum = -_INFINITY; 36 | sum = 0; 37 | for(j = mid + 1 ; j <= high ; j ++) 38 | { 39 | sum = sum + A[j]; 40 | if(sum > rightsum) 41 | { 42 | rightsum = sum; 43 | maxright = j; 44 | } 45 | } 46 | return (maxleft,maxright, leftsum + rightsum); 47 | } 48 | int FindMaximumSubarray(int A[M], int low, int high) 49 | { 50 | if(high == low) { 51 | return (low, high, A[low]); 52 | } 53 | else { 54 | int mid = (low + high) / 2; 55 | int crosslow, crosshigh, crosssum; 56 | int leftlow, lefthigh, leftsum, rightsum, rightlow, righthigh; 57 | 58 | (leftlow, lefthigh, leftsum) = FindMaximumSubarray(A, low, mid); 59 | (rightlow, righthigh, rightsum) = FindMaximumSubarray(A, mid + 1, high); 60 | (crosslow, crosshigh, crosssum) = FindMaxCrossingSubarray(A, low, mid, high); 61 | 62 | if(leftsum >= rightsum && leftsum >= crosssum) 63 | return (leftlow, lefthigh, leftsum); 64 | else if(rightsum >= leftsum && rightsum >= crosssum) 65 | return (rightlow, righthigh, rightsum); 66 | else return (crosslow, crosshigh, crosssum); 67 | } 68 | } 69 | 70 | int main() 71 | { 72 | cin >> n; 73 | for (int i = 1; i <= n; i ++) cin >> a[i]; 74 | cout << FindMaximumSubarray(a, 1, n) << endl; 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /Miller-Rabin Primaility test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define mp make_pair 6 | #define pb push_back 7 | #define y1 lalalalalala 8 | #define index lalalalalalala 9 | #define show(a, i) cout << "a[" << i << "] = " << a[i] << endl; 10 | #define all(x) x.begin(), x.end() 11 | #define vi vector 12 | #define ll unsigned long long 13 | 14 | const int INF = 1e9 + 1; 15 | 16 | int getint() 17 | { 18 | char ch; 19 | int neg = 1; 20 | int val = 0; 21 | 22 | while(ch = getchar()) 23 | { 24 | if(ch == '-') neg = -1; 25 | else if(ch > 57 || ch < 48) break; 26 | else val = 10 * val + ch - 48; 27 | } 28 | val = val * neg; 29 | return val; 30 | } 31 | 32 | const int cs = 1e5 + 1; 33 | 34 | ll n; 35 | vectorp; 36 | 37 | void getprimes() 38 | { 39 | int up = (int)sqrt(1.e9 + 1); 40 | vectoru(up + 1, 0); 41 | 42 | for(int i = 2 ; i <= (int)sqrt(up) ; i ++) 43 | if(!u[i]) 44 | for(int j = i * i ; j < up ; j += i) 45 | u[j] = 1; 46 | 47 | for(int i = 2 ; i < up ; i ++) 48 | if(!u[i]) 49 | p.pb(i); 50 | } 51 | 52 | ll mul(ll a, ll b, ll c) 53 | { 54 | if(b == 0) 55 | return 0; 56 | 57 | ll temp = mul(a, b >> 1, c); 58 | temp = temp << 1; 59 | temp %= c; 60 | if(b & 1) 61 | { 62 | temp += a; 63 | temp %= c; 64 | } 65 | return temp; 66 | } 67 | ll modpow(ll a, ll b, ll c) 68 | { 69 | if(b == 0) 70 | return 1; 71 | 72 | ll temp = modpow(a, b >> 1, c); 73 | 74 | temp = mul(temp, temp, c); 75 | 76 | if(b & 1) 77 | temp = mul(temp, a, c); 78 | 79 | return temp; 80 | } 81 | 82 | bool pseudoprime(ll n) 83 | { 84 | return modpow(2, n - 1, n) == 1; 85 | } 86 | 87 | int Tries(ll n) 88 | { 89 | /// returns how many numbers will be checked as a witness 90 | /// if it is big, error rate will so little... 91 | return (int)log2(n) + 1; 92 | } 93 | 94 | bool Witness(ll r, ll n) 95 | { 96 | ll m = n - 1; 97 | 98 | int s = 0; 99 | while(!(m & 1)) 100 | { 101 | s ++; 102 | m = m >> 1; 103 | } 104 | 105 | vectorx(s + 1, 0); 106 | 107 | x[0] = modpow(r, m, n); 108 | 109 | for(int i = 1 ; i <= s ; i ++) 110 | { 111 | x[i] = mul(x[i - 1], x[i - 1], n); 112 | 113 | if(x[i] == 1 && x[i - 1] != 1 && x[i - 1] != n - 1) 114 | return true; 115 | } 116 | if(x[s] != 1) 117 | return true; 118 | return false; 119 | } 120 | 121 | bool solve_small(ll n) 122 | { 123 | if(n == 1) 124 | return false; 125 | int up = (int)sqrt(n); 126 | for(auto i : p) 127 | { 128 | if(i > up) 129 | break; 130 | if(n % i == 0) 131 | return false; 132 | } 133 | return true; 134 | } 135 | 136 | bool Miller_Rabin(ll n) 137 | { 138 | if(n < (1 << 30)) 139 | return solve_small(n); 140 | 141 | if(!pseudoprime(n)) 142 | return false; 143 | 144 | int s = Tries(n); 145 | 146 | for(int i = 0 ; i < s ; i ++) 147 | { 148 | ll r = p[i]; 149 | 150 | if(r >= n) 151 | break; 152 | 153 | if(n % r == 0 || Witness(r, n) == true) 154 | return false; 155 | } 156 | return true; 157 | } 158 | 159 | int main() 160 | { 161 | ios_base::sync_with_stdio(false); 162 | cin.tie(false); 163 | 164 | getprimes(); 165 | 166 | 167 | int t; 168 | 169 | cin >> t; 170 | 171 | while(t --) 172 | { 173 | cin >> n; 174 | 175 | if(Miller_Rabin(n) == true) 176 | cout << "YES" << endl; 177 | else cout << "NO" << endl; 178 | } 179 | ///cerr << "Elapsed time: " << 1.0 * clock() / CLOCKS_PER_SEC << " sec" << endl; 180 | return 0; 181 | } 182 | -------------------------------------------------------------------------------- /Order-statistic tree (set).cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | //#pragma comment(linker, "/STACK:100000000") 3 | 4 | #include 5 | 6 | using namespace std; 7 | 8 | #define mp make_pair 9 | #define pb push_back 10 | #define y1 lalalalalala 11 | #define index lalalalalalala 12 | #define show(a, i) cout << "a[" << i << "] = " << a[i] << endl; 13 | #define all(x) x.begin(), x.end() 14 | #define vi vector 15 | #define pii pair 16 | #define ll long long 17 | 18 | 19 | #include 20 | #include 21 | 22 | using namespace __gnu_pbds; 23 | 24 | const int INF = 1e9 + 1; 25 | 26 | int getint() 27 | { 28 | char ch; 29 | int neg = 1; 30 | int val = 0; 31 | 32 | while(ch = getchar()) 33 | { 34 | if(ch == '-') neg = -1; 35 | else if(ch > 57 || ch < 48) break; 36 | else val = 10 * val + ch - 48; 37 | } 38 | val = val * neg; 39 | return val; 40 | } 41 | 42 | typedef 43 | tree< 44 | int, 45 | null_type, 46 | greater, 47 | rb_tree_tag, 48 | 49 | tree_order_statistics_node_update> 50 | set_t; 51 | 52 | set_t s; 53 | int main() 54 | { 55 | int n, f, x; 56 | 57 | cin >> n; 58 | while(n --) 59 | { 60 | cin >> f; 61 | cin >> x; 62 | if(f == 1) s.insert(x); 63 | else if(f == -1) s.erase(x); 64 | else cout << *(s.find_by_order(x - 1)) << endl; 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Original Decart tree.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 12/6/17. 6 | // Copyright © 2017 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | 19 | struct node { 20 | int nodeValue; 21 | int subtreeSize; 22 | int subtreeValue; 23 | int priority; 24 | bool reversed; 25 | node* leftChild; 26 | node* rightChild; 27 | node () { 28 | 29 | } 30 | }; 31 | typedef node* tree; 32 | 33 | int getSize(tree &t) { 34 | return t ? t->subtreeSize : 0; 35 | } 36 | int getValue(tree &t) { 37 | return t ? t->subtreeValue : 0; 38 | } 39 | void update(tree &t) { 40 | if (t) { 41 | t->subtreeSize = getSize(t->leftChild) + 1 + getSize(t->rightChild); 42 | t->subtreeValue = max({getValue(t->leftChild), t->nodeValue, getValue(t->rightChild)}); 43 | } 44 | } 45 | void relax(tree &t) { 46 | if (t && t->reversed) { 47 | update(t); 48 | t->reversed = false; 49 | swap(t->leftChild, t->rightChild); 50 | if (t->leftChild) t->leftChild->reversed ^= true; 51 | if (t->rightChild) t->rightChild->reversed ^= true; 52 | } 53 | } 54 | tree initialize(int key) { 55 | tree t = (tree)malloc(sizeof(node)); 56 | t->nodeValue = key; 57 | t->subtreeSize = 1; 58 | t->subtreeValue = key; 59 | t->priority = rand(); 60 | t->reversed = false; 61 | t->leftChild = NULL; 62 | t->rightChild = NULL; 63 | return t; 64 | } 65 | void Split(tree &t, tree &l, tree &r, int position, int skipped = 0) { 66 | if (!t) return void(l = r = NULL); 67 | int currentPosition = skipped + getSize(t->leftChild) + 1; 68 | if (currentPosition <= position) { 69 | Split(t->rightChild, t->rightChild, r, position, currentPosition); 70 | l = t; 71 | } 72 | else { 73 | Split(t->leftChild, l, t->leftChild, position, skipped); 74 | r = t; 75 | } 76 | update(t); 77 | } 78 | void Merge(tree &t, tree &l, tree &r) { 79 | if (!l || !r) t = l ? l : r; 80 | else if(l->priority > r->priority) { 81 | Merge(l->rightChild, l->rightChild, r); 82 | t = l; 83 | } 84 | else { 85 | Merge(r->leftChild, l, r->leftChild); 86 | t = r; 87 | } 88 | update(t); 89 | } 90 | void Insert(tree &t, int position, int key) { 91 | tree l, r; 92 | tree current = initialize(key); 93 | Split(t, l, r, position - 1); 94 | Merge(l, l, current); 95 | Merge(t, l, r); 96 | } 97 | void Erase(tree &t, int position) { 98 | tree l, r; 99 | Split(t, l, r, position - 1); 100 | tree lx, rx; 101 | Split(r, lx, rx, 1); 102 | free(lx); 103 | Merge(t, l, rx); 104 | } 105 | bool Exists(tree &t, int key) { 106 | if (!t) return false; 107 | if (t->nodeValue == key) return true; 108 | if (t->nodeValue > key) return Exists(t->leftChild, key); 109 | else return Exists(t->rightChild, key); 110 | } 111 | int _getIndex(tree &t, int key, int skipped = 0) { // lower_bound 112 | if (t->nodeValue == key) return skipped + getSize(t->leftChild) + 1; 113 | if (t->nodeValue > key) return _getIndex(t->leftChild, skipped); 114 | else return _getIndex(t->rightChild, skipped + getSize(t->leftChild) + 1); 115 | } 116 | int getIndex(tree &t, int key) { 117 | if (!Exists(t, key)) return -1; 118 | return _getIndex(t, key); 119 | } 120 | 121 | void Print(tree &t) { 122 | if (!t) return; 123 | Print(t->leftChild); 124 | cout << t->nodeValue << " "; 125 | Print(t->rightChild); 126 | } 127 | 128 | int main() { 129 | srand(unsigned(time((NULL)))); 130 | 131 | tree t = NULL; 132 | for (int i = 0; i < 5; i ++) { 133 | Insert(t, i + 1, i + 1); 134 | } 135 | Print(t); cout << endl; 136 | Insert(t, 1, 6); 137 | Print(t); cout << endl; 138 | 139 | 140 | return 0; 141 | } 142 | 143 | -------------------------------------------------------------------------------- /Persistent segment tree (Kth element query).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | // http://www.spoj.com/problems/MKTHNUM/ 3 | using namespace std; 4 | 5 | const int me = 100025; 6 | 7 | typedef struct node{ 8 | int value; 9 | node *l, *r; 10 | } node; 11 | typedef node* pnode; 12 | 13 | int n, m, l, r, k; 14 | int a[me], v[me]; 15 | pnode roots[me]; 16 | pnode dummy = NULL; 17 | 18 | pnode Init(int value){ 19 | pnode p = (pnode)malloc(sizeof(node)); 20 | p->value = value; 21 | p->l = NULL; 22 | p->r = NULL; 23 | return p; 24 | } 25 | void Relax(pnode &root){ 26 | if(root->l) 27 | root->value += root->l->value; 28 | if(root->r) 29 | root->value += root->r->value; 30 | } 31 | int get_value(pnode &root){ 32 | return root? root->value : 0; 33 | } 34 | pnode add_node(pnode &cur, int low, int high, int pos, int value){ 35 | if(low > high) 36 | return dummy; 37 | if(!cur) 38 | cur = Init(0); 39 | if(low == pos && high == pos){ 40 | return Init(value); 41 | } 42 | int mid = (low + high) >> 1; 43 | pnode p = Init(0); 44 | if(pos <= mid){ 45 | p->l = add_node(cur->l, low, mid, pos, value); 46 | p->r = cur->r; 47 | } 48 | else{ 49 | p->l = cur->l; 50 | p->r = add_node(cur->r, mid + 1, high, pos, value); 51 | } 52 | Relax(p); 53 | return p; 54 | } 55 | int get(pnode &root, int low, int high, int l, int r){ 56 | if(low > high || low > r || high < l) 57 | return 0; 58 | if(!root) 59 | root = Init(0); 60 | if(low >= l && high <= r) 61 | return root->value; 62 | int mid = (low + high) >> 1; 63 | return get(root->l, low, mid, l, r) 64 | + get(root->r, mid + 1, high, l, r); 65 | } 66 | int Kth_element(pnode &cur_left, pnode &cur_right, int low, int high, int k){ 67 | if(!cur_left) 68 | cur_left = Init(0); 69 | if(!cur_right) 70 | cur_right = Init(0); 71 | if(low == high) 72 | return low; 73 | int mid = (low + high) >> 1; 74 | int sum = get_value(cur_right->l) - get_value(cur_left->l); 75 | if(sum >= k) 76 | return Kth_element(cur_left->l, cur_right->l, low, mid, k); 77 | else return Kth_element(cur_left->r, cur_right->r, mid + 1, high, k - sum); 78 | } 79 | void compress(){ 80 | map m, pos; 81 | for(int i = 1; i <= n; i ++) 82 | m[ a[i] ] = 1; 83 | int ptr = 1; 84 | for(auto i : m) 85 | pos[i.first] = ptr ++; 86 | for(int i = 1; i <= n; i ++){ 87 | int value = a[i]; 88 | a[i] = pos[ a[i] ]; 89 | v[ a[i] ] = value; 90 | } 91 | } 92 | 93 | int main(){ 94 | //ios_base::sync_with_stdio(0); 95 | //cin.tie(0); 96 | 97 | scanf("%d%d", &n, &m); 98 | for(int i = 1; i <= n; i ++) 99 | scanf("%d", &a[i]); 100 | compress(); 101 | for(int i = 1; i <= n; i ++) 102 | roots[i] = add_node(roots[i - 1], 1, n, a[i], 1); 103 | for(int i = 0; i < m; i ++){ 104 | scanf("%d%d%d", &l, &r, &k); 105 | printf("%d\n", v[Kth_element(roots[l - 1], roots[r], 1, n, k)]); 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /Persistent segment tree array implementation.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 04/10/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | const int MAX = 1000005; 16 | 17 | struct node { 18 | long long sum = -1; 19 | int leftChildID = 0; 20 | int rightChildID = 0; 21 | node () { 22 | 23 | } 24 | node (long long sum, int l, int r) 25 | :sum(sum), leftChildID(l), rightChildID(r) { 26 | 27 | } 28 | }; 29 | 30 | long long get(node p) { 31 | return p.sum == -1 ? 0 : p.sum; 32 | } 33 | 34 | node pool[MAX << 4]; 35 | int offset = 0; 36 | 37 | void add(node &root, int low, int high, int position, int value) { 38 | //if (!root.active) root = pool[++offset]; 39 | if (low == high) { 40 | root.sum += value; 41 | return; 42 | } 43 | int middle = (low + high) >> 1; 44 | if (position <= middle) { 45 | if (!root.leftChildID) { 46 | root.leftChildID = ++offset; 47 | pool[root.leftChildID].sum = 0; 48 | } 49 | add(pool[root.leftChildID], low, middle, position, value); 50 | } 51 | else { 52 | if (!root.rightChildID) { 53 | root.rightChildID = ++offset; 54 | pool[root.rightChildID].sum = 0; 55 | } 56 | add(pool[root.rightChildID], middle + 1, high, position, value); 57 | } 58 | root.sum = get(pool[root.leftChildID]) + get(pool[root.rightChildID]); 59 | } 60 | 61 | long long get(node &root, int low, int high, int l, int r) { 62 | if (root.sum == -1) return 0; 63 | if (low > r || high < l) return 0; 64 | if (low >= l && high <= r) return root.sum; 65 | int middle = (low + high) >> 1; 66 | return get(pool[root.leftChildID], low, middle, l, r) 67 | + get(pool[root.rightChildID], middle + 1, high, l, r); 68 | } 69 | 70 | template 71 | void fastInput(T &N) { 72 | char ch; 73 | int sign = 1; 74 | N = 0; 75 | while ((ch = getchar_unlocked()) && ch == ' ') {}; 76 | if (ch == '-') sign = -1; 77 | else if (isdigit(ch)) N = ch - '0'; 78 | while ((ch = getchar_unlocked()) && isdigit(ch)) { 79 | N = (N << 1) + (N << 3) + ch - '0'; 80 | } 81 | if (sign == -1) N = ~N + 1; 82 | } 83 | template void fastPrint(T &n){ 84 | if(n == 0){ 85 | puts("0"); 86 | return; 87 | } 88 | char buffer[256]; 89 | int ptr = 0, sign = 1; 90 | 91 | if(n < 0){ 92 | sign = -1; 93 | n *= -1; 94 | } 95 | while(n > 0){ 96 | buffer[ptr ++] = (char)(n % 10 + '0'); 97 | n /= 10; 98 | } 99 | if(sign == -1) 100 | putchar_unlocked('-'); 101 | for(int i = ptr - 1; i >= 0; i --) 102 | putchar_unlocked(buffer[i]); 103 | putchar_unlocked('\n'); 104 | } 105 | 106 | int N, Q; 107 | int p[MAX], lp[MAX]; 108 | node roots[MAX]; 109 | 110 | int main() { 111 | for (int i = 2; i < MAX; i ++) { 112 | if (p[i]) continue; 113 | for (int j = i; j < MAX; j += i) { 114 | p[j] ++; 115 | lp[j] = i; 116 | } 117 | } 118 | 119 | //scanf("%d%d", &N, &Q); 120 | fastInput(N); 121 | fastInput(Q); 122 | 123 | for (int i = 1; i < MAX; i ++) { 124 | if (p[i] == 1) { 125 | roots[i] = pool[++offset]; 126 | roots[i].sum = 0; 127 | } 128 | } 129 | 130 | for (int i = 1; i <= N; i ++) { 131 | int x, y; 132 | //scanf("%d", &x); 133 | fastInput(x); 134 | y = x; 135 | while (x > 1) { 136 | int d = 1, v = lp[x]; 137 | while (x % v == 0) { 138 | x /= v; 139 | d *= v; 140 | } 141 | add(roots[d], 1, N, i, y); 142 | } 143 | } 144 | while (Q --) { 145 | int l, r, p; 146 | //scanf("%d%d%d", &l, &r, &p); 147 | fastInput(l); 148 | fastInput(r); 149 | fastInput(p); 150 | long long result = 0; 151 | for (int i = p; i < MAX; ) { 152 | result += get(roots[i], 1, N, l, r) * (i - 1) / i; 153 | if (i > (MAX - 1) / p) break; 154 | else i *= p; 155 | } 156 | //printf("%lld\n", result); 157 | fastPrint(result); 158 | } 159 | 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /Quadtree 2D querying.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 12/02/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /* 10 | Quadtree implementation for 2D aggregate functions handling 11 | Wikipedia page for quadtrees: https://en.wikipedia.org/wiki/Quadtree 12 | The implementation below solves the following "Mineral Mining" problem: 13 | - You are given set of N points in 2D plane with fixed aggregate value 14 | - And you get Q queries in the following form: 15 | - each query consists of M rectangles with sides parallel to coordinate axes 16 | - you are required to find the total sum (aggregate function) of all the points 17 | lying in union of these rectangles 18 | 19 | Building the tree O(N * log(N)) 20 | Complexity of answering a set of only one query: O(M * log^2(N)) on average 21 | Since we need to preserve the data structure for successive queries, a roll-back routine 22 | is required (O(M * log^2(N))) 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace std; 34 | 35 | const int MAX_SIZE = 1 << 19; 36 | 37 | struct point{ 38 | int x; 39 | int y; 40 | int value; 41 | point() { 42 | 43 | } 44 | point(int __x, int __y, int __value) { 45 | x = __x; 46 | y = __y; 47 | value = __value; 48 | } 49 | }; 50 | struct rectangle{ 51 | int xLow, yLow; 52 | int xHigh, yHigh; 53 | rectangle() { 54 | 55 | } 56 | rectangle(int x, int y, int X, int Y) { 57 | xLow = min(x, X); 58 | yLow = min(y, Y); 59 | xHigh = max(x, X); 60 | yHigh = max(y, Y); 61 | } 62 | }; 63 | struct query{ 64 | int n; 65 | vector qrecs; 66 | query() { 67 | 68 | } 69 | query(int __n, vector __qrecs) { 70 | n = __n; 71 | qrecs = __qrecs; 72 | } 73 | }; 74 | 75 | int N, Q; 76 | vector bases; 77 | vector queries; 78 | 79 | int xRange, yRange; 80 | vector xCoords; 81 | vector yCoords; 82 | 83 | int stree[MAX_SIZE << 2], lazy[MAX_SIZE << 2]; 84 | 85 | void add(int I, int lowx, int highx, int lowy, int highy, int x, int y, int value) { 86 | if (lowx == highx && lowy == highy) { 87 | stree[I] += value; 88 | lazy[I] = stree[I]; 89 | return; 90 | } 91 | int middlex = (lowx + highx) >> 1; 92 | int middley = (lowy + highy) >> 1; 93 | if (x <= middlex && y <= middley) { 94 | add(I * 4 - 2, lowx, middlex, lowy, middley, x, y, value); 95 | } else if (x <= middlex) { 96 | add(I * 4 - 1, lowx, middlex, middley + 1, highy, x, y, value); 97 | } else if (x > middlex && y <= middley) { 98 | add(I * 4, middlex + 1, highx, lowy, middley, x, y, value); 99 | } else { 100 | add(I * 4 + 1, middlex + 1, highx, middley + 1, highy, x, y, value); 101 | } 102 | stree[I] = stree[I * 4 - 2] + stree[I * 4 - 1] + stree[I * 4] + stree[I * 4 + 1]; 103 | lazy[I] = stree[I]; 104 | } 105 | int get(int I, int lowx, int highx, int lowy, int highy, int x, int X, int y, int Y) { 106 | if (lazy[I] == 0) { 107 | return 0; 108 | } 109 | if (lowx > X || highx < x) { 110 | return 0; 111 | } if (lowy > Y || highy < y) { 112 | return 0; 113 | } if (lowx >= x && highx <= X && lowy >= y && highy <= Y) { 114 | int v = lazy[I]; 115 | lazy[I] = 0; 116 | return v; 117 | } 118 | int middlex = (lowx + highx) >> 1; 119 | int middley = (lowy + highy) >> 1; 120 | int sum = 0; 121 | sum += get(I * 4 - 2, lowx, middlex, lowy, middley, x, X, y, Y); 122 | sum += get(I * 4 - 1, lowx, middlex, middley + 1, highy, x, X, y, Y); 123 | sum += get(I * 4, middlex + 1, highx, lowy, middley, x, X, y, Y); 124 | sum += get(I * 4 + 1, middlex + 1, highx, middley + 1, highy, x, X, y, Y); 125 | lazy[I] = lazy[I * 4 - 2] + lazy[I * 4 - 1] + lazy[I * 4] + lazy[I * 4 + 1]; 126 | return sum; 127 | } 128 | void rollBack(int I, int lowx, int highx, int lowy, int highy, int x, int X, int y, int Y) { 129 | if (lowx > X || highx < x) { 130 | return; 131 | } if (lowy > Y || highy < y) { 132 | return; 133 | } if (lowx >= x && highx <= X && lowy >= y && highy <= Y) { 134 | lazy[I] = stree[I]; 135 | return; 136 | } 137 | int middlex = (lowx + highx) >> 1; 138 | int middley = (lowy + highy) >> 1; 139 | rollBack(I * 4 - 2, lowx, middlex, lowy, middley, x, X, y, Y); 140 | rollBack(I * 4 - 1, lowx, middlex, middley + 1, highy, x, X, y, Y); 141 | rollBack(I * 4, middlex + 1, highx, lowy, middley, x, X, y, Y); 142 | rollBack(I * 4 + 1, middlex + 1, highx, middley + 1, highy, x, X, y, Y); 143 | lazy[I] = lazy[I * 4 - 2] + lazy[I * 4 - 1] + lazy[I * 4] + lazy[I * 4 + 1]; 144 | } 145 | 146 | 147 | int main() { 148 | freopen("input.txt", "r", stdin); 149 | freopen("output.txt", "w", stdout); 150 | 151 | scanf("%d", &N); 152 | for (int i = 0; i < N; i ++) { 153 | int x, y, v; 154 | scanf("%d%d%d", &x, &y, &v); 155 | bases.push_back(point(x, y, v)); 156 | xCoords.push_back(x); 157 | yCoords.push_back(y); 158 | } 159 | scanf("%d", &Q); 160 | while (Q --) { 161 | query q; 162 | scanf("%d", &q.n); 163 | for (int i = 0; i < q.n; i ++) { 164 | int x, y, X, Y; 165 | scanf("%d%d%d%d", &x, &y, &X, &Y); 166 | q.qrecs.push_back(rectangle(x, y, X, Y)); 167 | xCoords.push_back(x); 168 | xCoords.push_back(X); 169 | yCoords.push_back(y); 170 | yCoords.push_back(Y); 171 | } 172 | queries.push_back(q); 173 | } 174 | sort(xCoords.begin(), xCoords.end()); 175 | sort(yCoords.begin(), yCoords.end()); 176 | xCoords.erase(unique(xCoords.begin(), xCoords.end()), xCoords.end()); 177 | yCoords.erase(unique(yCoords.begin(), yCoords.end()), yCoords.end()); 178 | 179 | xRange = (int)xCoords.size(); 180 | yRange = (int)yCoords.size(); 181 | // xRange = 1024; 182 | // yRange = 1024; 183 | for (auto &p: bases) { 184 | p.x = (int)(lower_bound(xCoords.begin(), xCoords.end(), p.x) - xCoords.begin()) + 1; 185 | p.y = (int)(lower_bound(yCoords.begin(), yCoords.end(), p.y) - yCoords.begin()) + 1; 186 | } for (auto &q: queries) { 187 | for (auto &qr: q.qrecs) { 188 | qr.xLow = (int)(lower_bound(xCoords.begin(), xCoords.end(), qr.xLow) - xCoords.begin()) + 1; 189 | qr.yLow = (int)(lower_bound(yCoords.begin(), yCoords.end(), qr.yLow) - yCoords.begin()) + 1; 190 | qr.xHigh = (int)(lower_bound(xCoords.begin(), xCoords.end(), qr.xHigh) - xCoords.begin()) + 1; 191 | qr.yHigh = (int)(lower_bound(yCoords.begin(), yCoords.end(), qr.yHigh) - yCoords.begin()) + 1; 192 | } 193 | } 194 | for (auto &p: bases) { 195 | add(1, 1, xRange, 1, yRange, p.x, p.y, p.value); 196 | } 197 | vector results; 198 | for (auto &q: queries) { 199 | int sum = 0; 200 | for (auto &qr: q.qrecs) { 201 | sum += get(1, 1, xRange, 1, yRange, qr.xLow, qr.xHigh, qr.yLow, qr.yHigh); 202 | } for (auto &qr: q.qrecs) { 203 | rollBack(1, 1, xRange, 1, yRange, qr.xLow, qr.xHigh, qr.yLow, qr.yHigh); 204 | } 205 | results.push_back(sum); 206 | } 207 | for (int i = 0; i < (int)results.size(); i ++) { 208 | printf("%d", results[i]); 209 | if (i < (int)results.size() - 1) { 210 | printf("\n"); 211 | } 212 | } 213 | 214 | return 0; 215 | } 216 | -------------------------------------------------------------------------------- /Quicksort hack halyavin.cpp: -------------------------------------------------------------------------------- 1 | // Hacking quicksort solutions during competitions 2 | // The code belongs to Halyavin (CF handle). 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | std::vector anti_sort(size_t n) { 12 | std::vector res(2 * n + 1); 13 | std::iota(res.begin(), res.end(), 0); 14 | for (size_t i = n; i-- > 0;) { 15 | std::swap(res[2 * i + 1], res[i + n]); 16 | } 17 | return res; 18 | } 19 | 20 | void genB(std::ostream &out) { 21 | std::vector gen = anti_sort(49999); 22 | int n = gen.size(); 23 | out << n << std::endl; 24 | for (int i = 0; i < n; i++) { 25 | if (i > 0) { 26 | out << " "; 27 | } 28 | out << gen[i] + 1; 29 | } 30 | out << std::endl; 31 | } 32 | 33 | int main() { 34 | std::cin.sync_with_stdio(false); 35 | std::cin.tie(nullptr); 36 | genB(std::cout); 37 | return 0; 38 | } 39 | 40 | 41 | 42 | //// hacked solution: 43 | #include 44 | #include 45 | 46 | int cmpfunc(const void *a, const void *b){ 47 | return *(const long long int*)a - *(const long long int *)b; 48 | } 49 | 50 | 51 | int main(void){ 52 | long long int n,i,j,sum,ans; 53 | long long int arr[100005]; 54 | scanf("%lli",&n); 55 | for(i = 0; i < n; i++){ 56 | scanf("%lli",&arr[i]); 57 | } 58 | qsort(arr,n,sizeof arr[0],cmpfunc); 59 | ans = 0; 60 | for(i = 1; i <= 35; i++){ 61 | sum = 1LL << i; 62 | for(j = 0; j < n - 1; j++){ 63 | if(arr[j] >= sum){ 64 | break; 65 | } 66 | else{ 67 | long long int start,middle,end,front,back; 68 | long long int target = sum - arr[j]; 69 | // printf("%lli %lli %lli\n",sum,arr[j],target); 70 | start = j + 1; 71 | end = n - 1; 72 | if(arr[start] <= target && arr[end] >= target){ 73 | if(arr[start] == target){ 74 | front = start; 75 | } 76 | else{ 77 | while(start < end - 1){ 78 | middle = (start + end)/2; 79 | if(arr[middle] < target){ 80 | start = middle; 81 | } 82 | else{ 83 | end = middle; 84 | } 85 | } 86 | if(arr[start+1] == target){ 87 | front = start + 1; 88 | } 89 | } 90 | if(arr[n-1] == target){ 91 | back = n-1; 92 | } 93 | else{ 94 | back = n-1; 95 | start = front; 96 | while(start < back - 1){ 97 | middle = (start + back)/2; 98 | if(arr[middle] > target){ 99 | back = middle; 100 | } 101 | else{ 102 | start = middle; 103 | } 104 | } 105 | back--; 106 | } 107 | if(arr[front] == target){ 108 | ans += back - front +1; 109 | } 110 | // printf("%lli %lli %lli %lli\n",target,j,front,back); 111 | } 112 | } 113 | } 114 | } 115 | printf("%lli\n",ans); 116 | } 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Implementations for some most used algorithms 2 | Codes have mostly been written in C++. Please, consider compiling the code using C++11 or higher to avoid any compilation issues or warnings. 3 | 4 | The list of implemented algorithms: 5 | 1. 2D Fenwick tree implementation using static arrays. 6 | - Point updates or range queries are handled in O(log^2(N)). 7 | - ~5x faster than pointer implementation 8 | 2. Finding Articulation points and bridges of graphs 9 | - Linear time implementation 10 | 3. Binary trie using static arrays 11 | - Implementation can be modified for larger alphabets 12 | - ~4x faster than pointer implementation 13 | 4. Building Cartesian trees in linear time 14 | 5. Finding the closest points in a set of 2D points in O(N * log(N)) 15 | 6. Decart tree with data references 16 | - Please, refer to the problem on the link in the file to understand what type of queries need to be handled 17 | - Expected O(log(N)) time approach to handle standard BST operations 18 | - Extra tree and dynamic array operations 19 | 7. Dijkstra with Min-Heap: 20 | - Manual implementation of the heap 21 | 8. Finding dynamic median: 22 | - Logarithmic solution to find median during series of update operations 23 | 9. Fast ternary search 24 | - O(log(2)(N)) performance instead of classic O(log(3/2)(N)) 25 | 10. Fibonacci matrix 26 | - 2x2 matrix implementation to calculate N-th Fibonacci number in O(log(N)) 27 | 11. Implicit segment tree implementation 28 | - It's pointer implementation, using the same approach in [1], static array implementation can be produced. 29 | - Update/Ask queries in O(log(RANGE)) 30 | 12. Johnson's all pairs shortest path problem 31 | - O(V * E * log(V)) overall complexity 32 | - Bellman-Ford algorithm is used to detect negative cycle(if any). 33 | 13. Karatsuba multiplication in O(N^1.58) 34 | - multiplication of large integers (big integer in CP) 35 | - Although FFT is O(N * log(N)), Karatsuba is handy when you do not have prewritten FFT code. 36 | 14. Kruskal Minimal Spanning Tree Algorithm in O(E * log(V)) 37 | - Union/Find data structure 38 | 15. Atkin's prime sieve in O(N) 39 | - Atkin's wheel ("WHEEL" variable in the code) can be adjusted 40 | 16. Linear prime sieve 41 | 17. MO's algorithm 42 | - Offline query handling 43 | 18. Finding farthest points based on Manhattan distance in 2D grid 44 | - O(N * log2(N)) 45 | - can be extended to larger dimensions O(N * 2^d * log2(N)) 46 | 19. Miller-Rabin primality test 47 | 20. Ordered set - Decart tree 48 | - Just more powerful than a BST 49 | 21. Persistent segment tree implementation 50 | - static array implementation 51 | - finding Kth element in any sorted subarray of elements in O(log(N)) 52 | 22. Hash table for comparing range of fixed objects 53 | 23. Rope - builtin decart tree 54 | 24. Basic String matching utilities 55 | - Z function 56 | - prefix function 57 | - KMP algorithm 58 | 25. Fast/ultrafast input & output for enermous input 59 | - getchar_unlocked() will probably produce some warnings (unsafe blabla...), you may replace it with getchar() 60 | 26. Multiplication bases and modulos for hash tables 61 | 27. A method to hack unordered_set solutions during competitions 62 | - The solution belongs to a coder who hacked my solution during one of Codeforces contests) 63 | 28. Quicksort hack by Halyavin 64 | - Some people still use qsort() function in C. The code produces adversary test cases. 65 | 29. Quadtree implementation for 2D aggregate queries 66 | 30. LCA with binary lifting 67 | - Preprocessing in O(N * log(N)) 68 | - LCA queries in O(log(N)) 69 | 31. Triangle counting in general graphs O(M^1.5) 70 | - M is the number of edges 71 | 32. Min-Stack: finding minimum elements in stack in O(1) 72 | 33. Huffman encoding via priority queues 73 | -------------------------------------------------------------------------------- /Range comparison using hashes.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 5/31/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | 10 | // refer to this problem 11 | // http://codeforces.com/gym/101808/problem/B 12 | // and tutorial 13 | // http://codeforces.com/blog/entry/59696 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | const int MAX = 4005; 24 | const int mods[] = {715225741, 1000000007}; 25 | const int bases[] = {555558019, 777781447}; 26 | 27 | int T, N; 28 | int id[MAX], h[2][MAX]; 29 | pair edges[MAX]; 30 | map, int> hashBlocks[MAX]; 31 | 32 | int power(int a, int b, int modulo) { 33 | if (b == 0) return 1 % modulo; 34 | if (b & 1) return 1LL * a * power(a, b - 1, modulo) % modulo; 35 | return power(1LL * a * a % modulo, b >> 1, modulo); 36 | } 37 | 38 | int main() { 39 | ios_base::sync_with_stdio(0); 40 | cin.tie(0); 41 | 42 | cin >> T; 43 | while (T --) { 44 | cin >> N; 45 | for (int i = 1; i <= N; i ++) { 46 | int u, v; 47 | cin >> u >> v; 48 | if (u > v) swap(u, v); 49 | edges[i] = make_pair(u, v); 50 | } 51 | vector> values = vector>(edges + 1, edges + N + 1); 52 | sort(values.begin(), values.end()); 53 | for (int i = 1; i <= N; i ++) { 54 | id[i] = (int)(lower_bound(values.begin(), values.end(), edges[i]) - values.begin()) + 1; 55 | h[0][i] = power(bases[0], id[i], mods[0]); 56 | h[1][i] = power(bases[1], id[i], mods[1]); 57 | } 58 | for (int i = 1; i <= N; i ++) { 59 | hashBlocks[i].clear(); 60 | } 61 | for (int i = 1; i <= N; i ++) { 62 | pair hashSum(0, 0); 63 | for (int j = i; j <= N; j ++) { 64 | hashSum.first = (hashSum.first + h[0][j]) % mods[0]; 65 | hashSum.second = (hashSum.second + h[1][j]) % mods[1]; 66 | hashBlocks[j - i + 1][hashSum] ++; 67 | } 68 | } 69 | int result = 0; 70 | for (int i = 1; i <= N; i ++) { 71 | for (auto j : hashBlocks[i]) { 72 | result += j.second * (j.second - 1) / 2; 73 | } 74 | } 75 | cout << result << endl; 76 | } 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /Rope(builtin decart tree).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | using namespace __gnu_cxx; 6 | 7 | const int me = 25; 8 | 9 | rope r; 10 | int n, m, a, b; 11 | int main() { 12 | ios_base::sync_with_stdio(0); 13 | cin.tie(0); 14 | 15 | cin >> n >> m; 16 | for(int i = 1; i <= n; i ++){ 17 | int x; 18 | cin >> x; 19 | r.push_back(x); 20 | } 21 | for(int i : r) 22 | cout << i << ", "; 23 | cout << endl; 24 | 25 | while(m --){ 26 | cin >> a >> b; 27 | a --, b --; 28 | rope s = r.substr(a, b - a + 1); 29 | r.erase(a, b - a + 1); 30 | r.insert(r.mutable_begin(), s); 31 | for(int i : r) 32 | cout << i << ", "; 33 | cout << endl; 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Simple Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define Long long long 6 | #define ld long double 7 | #define pii pair 8 | #define pli pair 9 | 10 | const int me = 100025; 11 | const int mod = 1.e9 + 7; 12 | 13 | class Trie{ 14 | private: 15 | const static int ALPHABET = 26; 16 | const static char FIRST_LETTER = 'a'; 17 | struct node{ 18 | int link[ALPHABET]; 19 | bool is_word; 20 | node(){ 21 | for(int i = 0; i < ALPHABET; i ++) 22 | link[i] = -1; 23 | is_word = false; 24 | } 25 | }; 26 | node make_node(){ 27 | node c = node(); 28 | return c; 29 | } 30 | int get(char x){ 31 | return x - FIRST_LETTER; 32 | } 33 | void traverse(int pos, string s){ 34 | if(trie[pos].is_word){ 35 | cout << "word: " << s << endl; 36 | } 37 | for(int i = 0; i < ALPHABET; i ++) 38 | if(trie[pos].link[i] != -1) 39 | traverse(trie[pos].link[i], s + (char)(i + 'a')); 40 | } 41 | 42 | public: 43 | vector trie; 44 | int Size; 45 | Trie(){ 46 | trie.push_back(make_node()); 47 | Size = 1; 48 | } 49 | ~Trie() { 50 | }; 51 | int size(){ 52 | return Size; 53 | } 54 | void add(string s){ 55 | int pos = 0; 56 | for(char i : s){ 57 | int x = get(i); 58 | if(trie[pos].link[x] == -1){ 59 | node c = make_node(); 60 | trie.push_back(c); 61 | trie[pos].link[x] = Size; 62 | pos = Size ++; 63 | } 64 | else{ 65 | pos = trie[pos].link[x]; 66 | } 67 | } 68 | trie[pos].is_word = true; 69 | } 70 | void output(){ 71 | traverse(0, ""); 72 | } 73 | }; 74 | 75 | 76 | int main() { 77 | ios_base::sync_with_stdio(0); 78 | cin.tie(0); 79 | 80 | Trie t = Trie(); 81 | t.add("abcd"); 82 | t.add("bdefd"); 83 | t.add("aaa"); 84 | t.add("abcc"); 85 | t.output(); 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /Simple decart tree (treap).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int me = 100025; 21 | 22 | typedef struct node{ 23 | int value; 24 | int subtree_value; 25 | int priority; 26 | int _cnt; 27 | node *l, *r; 28 | }node; 29 | typedef node* pnode; 30 | 31 | int get_value(pnode &t){ 32 | return t? t->subtree_value : INT_MAX; 33 | } 34 | int get_size(pnode &t){ 35 | return t? t->_cnt : 0; 36 | } 37 | void update_value(pnode &t){ 38 | if(t) 39 | t->subtree_value = min(get_value(t->l), 40 | min(t->value, get_value(t->r))); 41 | } 42 | void update_size(pnode &t){ 43 | if(t) 44 | t->_cnt = get_size(t->l) + 1 + get_size(t->r); 45 | } 46 | void Split(pnode t, pnode &l, pnode &r, int key){ 47 | if(!t) 48 | return void(l = r = NULL); 49 | if(t->value > key) 50 | Split(t->l, l, t->l, key), r = t; 51 | else Split(t->r, t->r, r, key), l = t; 52 | update_value(t); 53 | update_size(t); 54 | } 55 | void Merge(pnode &t, pnode l, pnode r){ 56 | if(!l || !r) 57 | t = l? l : r; 58 | else if(l->priority > r->priority) 59 | Merge(l->r, l->r, r), t = l; 60 | else Merge(r->l, l, r->l), t = r; 61 | update_value(t); 62 | update_size(t); 63 | } 64 | pnode Init(int key){ 65 | pnode p = pnode(malloc(sizeof(node))); 66 | p->value = p->subtree_value = key; 67 | p->priority = rand(); 68 | p->_cnt = 1; 69 | p->l = NULL; 70 | p->r = NULL; 71 | return p; 72 | } 73 | void Insert(pnode &t, int key){ 74 | pnode l, r; 75 | Split(t, l, r, key - 1); 76 | pnode p = Init(key); 77 | Merge(l, l, p); 78 | Merge(t, l, r); 79 | } 80 | bool Find(pnode &t, int key){ 81 | if(!t) 82 | return false; 83 | if(t->value == key) 84 | return true; 85 | if(t->value > key) 86 | return Find(t->l, key); 87 | return Find(t->r, key); 88 | } 89 | void Erase(pnode &t, int key){ 90 | if(!Find(t, key)) 91 | return; 92 | pnode l1, r1; 93 | Split(t, l1, r1, key - 1); 94 | pnode l2, r2; 95 | Split(r1, l2, r2, key); 96 | Merge(t, l1, r2); 97 | } 98 | int Order_of_key_utility(pnode &t, int key, int add = 0){ 99 | if(t->value == key) 100 | return add + get_size(t->l) + 1; 101 | int cur_pos = get_size(t->l) + add + 1; 102 | if(t->value > key) 103 | return Order_of_key_utility(t->l, key, add); 104 | return Order_of_key_utility(t->r, key, cur_pos); 105 | } 106 | int Order_of_key(pnode &t, int key){ 107 | if(!Find(t, key)) 108 | return -1; 109 | return Order_of_key_utility(t, key); 110 | } 111 | int Kth_element(pnode &t, int k){ 112 | if(get_size(t->l) + 1 == k) 113 | return t->value; 114 | if(get_size(t->l) + 1 > k) 115 | return Kth_element(t->l, k); 116 | return Kth_element(t->r, k - get_size(t->l) - 1); 117 | } 118 | void Print(pnode &t){ 119 | if(!t) 120 | return; 121 | Print(t->l); 122 | cout << t->value << endl; 123 | Print(t->r); 124 | } 125 | 126 | int main() { 127 | //ios_base::sync_with_stdio(0); 128 | //cin.tie(0); 129 | 130 | pnode t = NULL; 131 | for(int i = 0; i < 10; i ++){ 132 | string type; 133 | cin >> type; 134 | if(type == "insert"){ 135 | int a; 136 | cin >> a; 137 | Insert(t, a); 138 | } 139 | else if(type == "erase"){ 140 | int a; 141 | cin >> a; 142 | Erase(t, a); 143 | } 144 | else if(type == "order"){ 145 | int a; 146 | cin >> a; 147 | cout << Order_of_key(t, a) << endl; 148 | } 149 | else if(type == "kth"){ 150 | int a; 151 | cin >> a; 152 | cout << Kth_element(t, a) << endl; 153 | } 154 | else if(type == "print"){ 155 | Print(t); 156 | } 157 | else break; 158 | } 159 | return 0; 160 | } 161 | -------------------------------------------------------------------------------- /Smallest cyclic shift (Nlog^2(N)).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define Long long long 6 | #define ld long double 7 | #define pii pair 8 | #define pli pair 9 | 10 | const int me = 100025; 11 | const int mod = 1.e9 + 7; 12 | const int MAX_LOG = 20; 13 | 14 | struct node{ 15 | int value; 16 | int extra; 17 | int pos; 18 | 19 | node() {} 20 | node(int value, int extra, int pos) : value(value), extra(extra), pos(pos) {} 21 | bool operator < (const node other) const{ 22 | if(value != other.value) 23 | return value < other.value; 24 | return extra < other.extra; 25 | } 26 | }; 27 | 28 | int n, N, step; 29 | char s[me]; 30 | int p[MAX_LOG][me]; 31 | node v[me]; 32 | 33 | int lcp(int i, int j){ 34 | int ans = 0; 35 | for(int k = (int)log2(n); k >= 0 && i < n && j < n; k --) 36 | if(p[k][i] == p[k][j]){ 37 | ans += 1 << k; 38 | i += 1 << k; 39 | j += 1 << k; 40 | } 41 | return ans; 42 | } 43 | 44 | int naive(){ 45 | int S = 0; 46 | for(int i = 1; i < N; i ++){ 47 | for(int j = 0; j < N; j ++){ 48 | if(s[S + j] < s[i + j]) 49 | break; 50 | if(s[S + j] > s[i + j]){ 51 | S = i; 52 | break; 53 | } 54 | } 55 | } 56 | return S; 57 | } 58 | void gen(){ 59 | srand(time(NULL)); 60 | n = rand() % me; 61 | for(int i = 0; i < n; i ++) 62 | s[i] = (char)(rand() % 26 + 'a'); 63 | } 64 | 65 | int main() { 66 | //ios_base::sync_with_stdio(0); 67 | //cin.tie(0); 68 | 69 | gets(s); 70 | //gen(); 71 | N = strlen(s); 72 | for(int i = 0; i < N; i ++) 73 | s[i + N] = s[i]; 74 | n = N << 1; 75 | for(int i = 0; i < n; i ++) 76 | p[0][i] = s[i] - 'a'; 77 | for(int cnt = 1; cnt < n; cnt *= 2){ 78 | ++ step; 79 | for(int i = 0; i < n; i ++){ 80 | v[i].value = p[step - 1][i]; 81 | v[i].extra = (i + cnt < n) ? p[step - 1][i + cnt] : -1; 82 | v[i].pos = i; 83 | } 84 | sort(v, v + n); 85 | for(int i = 0; i < n; i ++) 86 | p[step][ v[i].pos ] = (i > 0 && v[i].value == v[i - 1].value && v[i].extra == v[i - 1].extra) ? p[step][ v[i - 1].pos ] : i; 87 | } 88 | int S = 0; 89 | for(int i = 1; i < N; i ++){ 90 | int c = lcp(S, i); 91 | if(c < N){ 92 | if(s[S + c] > s[i + c]) 93 | S = i; 94 | } 95 | } 96 | //cerr << S << endl; 97 | //cerr << naive() << endl; 98 | for(int i = S; i < S + N; i ++) 99 | putchar(s[i]); 100 | puts(""); 101 | 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /Triangle counting in graphs.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 01/07/19. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | /* 10 | Fast triangle counting for graphs 11 | O(M * sqrt(M)) compexity where M is the edge size of the graph 12 | Note that: The implementation removes multiple edges 13 | and do not consider same triples more than once. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | using namespace std; 28 | 29 | const int MAX_SIZE = 1 << 17; 30 | 31 | int N, M; 32 | int degrees[MAX_SIZE]; 33 | vector> edgeList; 34 | vector> graph; 35 | bitset adj[MAX_SIZE]; 36 | 37 | int main(int argc, const char * argv[]) { 38 | scanf("%d%d", &N, &M); 39 | for (int i = 0; i < M; i ++) { 40 | int u, v; 41 | scanf("%d%d", &u, &v); 42 | edgeList.push_back(make_pair(u, v)); 43 | } 44 | sort(edgeList.begin(), edgeList.end()); 45 | edgeList.erase(unique(edgeList.begin(), edgeList.end()), edgeList.end()); 46 | graph.resize(N + 1); 47 | for (auto edge: edgeList) { 48 | int u = edge.first; 49 | int v = edge.second; 50 | graph[u].push_back(v); 51 | graph[v].push_back(u); 52 | adj[u][v] = 1; 53 | adj[v][u] = 1; 54 | degrees[u] ++; 55 | degrees[v] ++; 56 | } 57 | int threshold = (int)sqrt(1. * M); 58 | vector heavyNodes; 59 | for (int i = 1; i <= N; i ++) { 60 | if (degrees[i] >= threshold) { 61 | heavyNodes.push_back(i); 62 | } 63 | } 64 | vector isHeavy(N + 1, 0); 65 | for (int i: heavyNodes) { 66 | isHeavy[i] = 1; 67 | } 68 | vector orders(N + 1); 69 | iota(orders.begin(), orders.end(), 1); 70 | sort(orders.begin(), orders.end(), [&](int u, int v) { 71 | if (degrees[u] != degrees[v]) { 72 | return degrees[u] < degrees[v]; 73 | } else { 74 | return u < v; 75 | } 76 | }); 77 | long long result = 0; 78 | for (int i = 0; i < (int)heavyNodes.size(); i ++) { 79 | for (int j = i + 1; j < (int)heavyNodes.size(); j ++) { 80 | for (int k = j + 1; k < (int)heavyNodes.size(); k ++) { 81 | int a = heavyNodes[i]; 82 | int b = heavyNodes[j]; 83 | int c = heavyNodes[k]; 84 | if (adj[a][b] && adj[a][c] && adj[b][c]) { 85 | result ++; 86 | } 87 | } 88 | } 89 | } 90 | for (auto edge: edgeList) { 91 | int u = edge.first; 92 | int v = edge.second; 93 | if (isHeavy[u] && isHeavy[v]) { 94 | continue; 95 | } if (orders[u] > orders[v]) { 96 | swap(u, v); 97 | } 98 | for (auto neighbor: graph[u]) { 99 | if (orders[neighbor] < orders[u]) { 100 | continue; 101 | } if (adj[v][neighbor]) { 102 | result ++; 103 | } 104 | } 105 | } 106 | cout << result << endl; 107 | 108 | return 0; 109 | } 110 | 111 | -------------------------------------------------------------------------------- /Z + Prefix + KMP.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // practice 4 | // 5 | // Created by Mahmud on 03/30/18. 6 | // Copyright © 2018 Mahmud. All rights reserved. 7 | // 8 | 9 | // from Mike Mirzayanov's lectures 10 | // O(N) calculation of Z-function 11 | // O(N) calculation of Prefix function 12 | // O(N + M) KMP 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | const int MAX = 100005; 21 | 22 | void calculate_ZFunction(int *z, string s) { 23 | int N = (int)s.size(); 24 | int l = 0; 25 | int r = 0; 26 | for (int i = 0; i < N; i ++) z[i] = 0; 27 | for (int i = 1; i < N; i ++) { 28 | if (r >= i) z[i] = min(z[i - l], r - i + 1); 29 | while (z[i] + i < N && s[z[i]] == s[z[i] + i]) z[i] ++; 30 | if (i + z[i] - 1 > r) { 31 | l = i; 32 | r = i + z[i] - 1; 33 | } 34 | } 35 | } 36 | void calculate_PrefixFunction(int *b, string s) { 37 | int N = (int)s.size(); 38 | for (int i = 0; i < N; i ++) b[i] = 0; 39 | for (int i = 1; i < N; i ++) { 40 | int k = b[i - 1]; 41 | while (k > 0 && s[k] != s[i]) k = b[k - 1]; 42 | if (s[k] == s[i]) b[i] = k + 1; 43 | } 44 | } 45 | void KMP(string text, string pattern) { 46 | int N = (int)text.size(); 47 | int M = (int)pattern.size(); 48 | int b[MAX]; 49 | calculate_PrefixFunction(b, pattern); 50 | 51 | int k = 0; 52 | for (int i = 0; i < N; i ++) { 53 | while (k > 0 && pattern[k] != text[i]) k = b[k - 1]; 54 | if (pattern[k] == text[i]) { 55 | k ++; 56 | if (k == M) { 57 | cout << "occurrence ends in " << i << endl; 58 | k = b[k - 1]; 59 | } 60 | } 61 | } 62 | } 63 | 64 | int z[MAX]; 65 | 66 | int main() { 67 | string s; 68 | cin >> s; 69 | int N = (int)s.size(); 70 | calculate_ZFunction(z, s); 71 | for (int i = 0; i < N; i ++) cout << z[i] << ", "; cout << endl; 72 | 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /fast I:O.cpp: -------------------------------------------------------------------------------- 1 | // fast in version 1 2 | 3 | template 4 | void fastInput(T &N) { 5 | char ch; 6 | int sign = 1; 7 | N = 0; 8 | while ((ch = getchar_unlocked()) && ch == ' ') {}; 9 | if (ch == '-') sign = -1; 10 | else if (isdigit(ch)) N = ch - '0'; 11 | while ((ch = getchar_unlocked()) && isdigit(ch)) { 12 | N = (N << 1) + (N << 3) + ch - '0'; 13 | } 14 | if (sign == -1) N = ~N + 1; 15 | } 16 | 17 | 18 | // fast in version 2 19 | 20 | template void fastInput(T &n){ 21 | char ch; 22 | int sign = 1; 23 | while(ch = getchar_unlocked(), isspace(ch)) { 24 | 25 | }; 26 | n = 0; 27 | if(ch == '-') 28 | sign = -1; 29 | else n = ch - '0'; 30 | while(ch = getchar_unlocked(), isdigit(ch)) 31 | n = (n << 3) + (n << 1) + ch - '0'; 32 | n *= sign; 33 | } 34 | 35 | 36 | // fast out 37 | 38 | template void fastPrint(T n){ 39 | if(n == 0){ 40 | puts("0"); 41 | return; 42 | } 43 | char buffer[256]; 44 | int ptr = 0, sign = 1; 45 | 46 | if(n < 0){ 47 | sign = -1; 48 | n *= -1; 49 | } 50 | while(n > 0){ 51 | buffer[ptr ++] = (char)(n % 10 + '0'); 52 | n /= 10; 53 | } 54 | if(sign == -1) 55 | putchar_unlocked('-'); 56 | for(int i = ptr - 1; i >= 0; i --) 57 | putchar_unlocked(buffer[i]); 58 | putchar_unlocked('\n'); 59 | } 60 | -------------------------------------------------------------------------------- /mods and muls.txt: -------------------------------------------------------------------------------- 1 | const int mods[] = {715225741, 1000000007}; 2 | const int muls[] = {43, 73}; 3 | const int bases[] = {555558019, 777781447}; 4 | 5 | // to debug 6 | const int mods[] = {1000000000, 1000000000}; 7 | const int muls[] = {10, 10}; 8 | -------------------------------------------------------------------------------- /trie class (implement).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | #define Long long long 6 | #define ld long double 7 | #define pii pair 8 | #define pli pair 9 | 10 | const int me = 100025; 11 | const int mod = 1.e9 + 7; 12 | 13 | class Trie{ 14 | private: 15 | const static int ALPHABET = 26; 16 | const static char FIRST_LETTER = 'a'; 17 | struct node{ 18 | int link[ALPHABET]; 19 | bool is_word; 20 | node(){ 21 | for(int i = 0; i < ALPHABET; i ++) 22 | link[i] = -1; 23 | is_word = false; 24 | } 25 | }; 26 | node make_node(){ 27 | node c = node(); 28 | return c; 29 | } 30 | int get(char x){ 31 | return x - FIRST_LETTER; 32 | } 33 | void traverse(int pos, string s){ 34 | if(trie[pos].is_word){ 35 | cout << "word: " << s << endl; 36 | } 37 | for(int i = 0; i < ALPHABET; i ++) 38 | if(trie[pos].link[i] != -1) 39 | traverse(trie[pos].link[i], s + (char)(i + 'a')); 40 | } 41 | 42 | public: 43 | vector trie; 44 | int Size; 45 | Trie(){ 46 | trie.push_back(make_node()); 47 | Size = 1; 48 | } 49 | ~Trie() { 50 | }; 51 | int size(){ 52 | return Size; 53 | } 54 | void add(string s){ 55 | int pos = 0; 56 | for(char i : s){ 57 | int x = get(i); 58 | if(trie[pos].link[x] == -1){ 59 | node c = make_node(); 60 | trie.push_back(c); 61 | trie[pos].link[x] = Size; 62 | pos = Size ++; 63 | } 64 | else{ 65 | pos = trie[pos].link[x]; 66 | } 67 | } 68 | trie[pos].is_word = true; 69 | } 70 | void output(){ 71 | traverse(0, ""); 72 | } 73 | }; 74 | 75 | 76 | int main() { 77 | ios_base::sync_with_stdio(0); 78 | cin.tie(0); 79 | 80 | Trie t = Trie(); 81 | t.add("abcd"); 82 | t.add("bdefd"); 83 | t.add("aaa"); 84 | t.add("abcc"); 85 | t.output(); 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /unordered_set hack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Can be used to hack unordered_set/map solutions 5 | in Codeforces and other similar online judges. 6 | Implementation was taken from Codeforces. 7 | */ 8 | 9 | using namespace std; 10 | 11 | const int me = 100025; 12 | 13 | int ar[100] = {0}; 14 | unordered_set S; 15 | 16 | int main() { 17 | srand(31); 18 | 19 | int k, x, pos = 0, c = 0, l = 0, i = 1; 20 | int n = 1e5; /// make n larger as possible 21 | printf("%d\n", n); 22 | 23 | for (i = 1; i <= n; i++) { 24 | x = ((rand() << 15) ^ rand()) % 1000000007 + 1; 25 | int lol = S.bucket_count(); 26 | if (lol >= 6){ 27 | c = ++ar[pos]; 28 | x = c * lol; 29 | if (x > 1000000000){ 30 | ar[pos] = 1; 31 | c = ar[pos]; 32 | x = c * lol; 33 | } 34 | 35 | while (S.count(x)) x += (rand() % 97); 36 | } 37 | while (S.count(x)) x += (rand() % 179371); 38 | 39 | if (x > 1000000000){ 40 | i--; 41 | continue; 42 | } 43 | //printf("%d", x); 44 | //if(i > 1) 45 | // putchar(' '); 46 | S.insert(x); 47 | k = S.bucket_count(); 48 | if (k != l) pos++; 49 | l = k; 50 | } 51 | puts(""); 52 | 53 | return 0; 54 | } 55 | --------------------------------------------------------------------------------