├── .gitignore ├── 2-Satisfiability.cpp ├── Aho-Corasick-Automaton.cpp ├── Bellman-Ford(Queue-Optimised).cpp ├── Bellman-Ford.cpp ├── Biconnected-Component.cpp ├── Bigraph-Matching(Edmonds-Karp).cpp ├── Bigraph-Matching(Improved-Shortest-Augmenting-Path).cpp ├── Binary-Search-Tree.cpp ├── Breadth-First-Search.cpp ├── Bubble-Sort.cpp ├── Bucket-Sort.cpp ├── Cartesian-Tree.cpp ├── Centre-of-Gravity(Polygon).cpp ├── Combination(Recursion).cpp ├── Combination.cpp ├── Complex-Number.cpp ├── Cut-Vertex.cpp ├── Depth-First-Search.cpp ├── Dijkstra(Heap-Optimised).cpp ├── Dinic.cpp ├── Disjoint-Set-Union.cpp ├── Edmonds-Karp.cpp ├── Euler's-Totient-Function-Sieve(Linear).cpp ├── Euler's-Totient-Function.cpp ├── Eulerian-Tour(Digraph).cpp ├── Extended-Euclid.cpp ├── Fast-Exponentiation.cpp ├── Fast-Fourier-Transform(Iterative).cpp ├── Fast-Number-Theoretic-Transform.cpp ├── Fenwick-Tree.cpp ├── Fibonacci-Heap.cpp ├── Floyd-Warshall.cpp ├── Gaussian-Elimination.cpp ├── Graham-Scan.cpp ├── Greatest-Common-Divisor.cpp ├── Heap-Sort.cpp ├── Heavy-Light-Decomposition.cpp ├── High-Precision(Integer).cpp ├── Hungarian-Algorithm.cpp ├── Improved-Shortest-Augmenting-Path(Gap-Optimised).cpp ├── Improved-Shortest-Augmenting-Path(Naive).cpp ├── Insertion-Sort.cpp ├── K-Dimensional-Tree.cpp ├── Knuth-Morris-Pratt.cpp ├── Kruskal.cpp ├── Least-Common-Ancestor(Tarjan).cpp ├── Leftist-Tree.cpp ├── Linear-Basis.cpp ├── Link-Cut-Tree(with-Reverse).cpp ├── Link-Cut-Tree.cpp ├── Longest-Common-Substring.cpp ├── Longest-Increasing-Subsequence(n·log(n)).cpp ├── Lowest-Common-Ancestor(Doubling).cpp ├── Matrix-Multiplication(Naive).cpp ├── Merge-Sort.cpp ├── Miller-Rabin.cpp ├── Min-Heap.cpp ├── Modular-Multiplicative-Inverse-Sieve(Factorial,Linear).cpp ├── Modular-Multiplicative-Inverse-Sieve(Linear).cpp ├── Modular-Multiplicative-Inverse.cpp ├── Non-Rotating-Treap.cpp ├── Palindromic-Tree.cpp ├── Permutation.cpp ├── Persistent-Array.cpp ├── Persistent-Segment-Tree(Sum).cpp ├── Persistent-Treap.cpp ├── Persistent-Trie.cpp ├── Prim.cpp ├── Prime-Check(Naive).cpp ├── Prime-Sieve(Linear).cpp ├── Primitive-Root.cpp ├── Prüfer-Sequence(Tree-to-Sequence).cpp ├── Queue.cpp ├── Quick-Sort(Extra-Optimised).cpp ├── Quick-Sort(Randomized).cpp ├── Quick-Sort.cpp ├── Radix-Sort.cpp ├── Reverse-Pair(Merge-Sort).cpp ├── Segment-Direction.cpp ├── Segment-Intersection.cpp ├── Segment-Tree(Minimum).cpp ├── Segment-Tree(Sum).cpp ├── Selection-Sort.cpp ├── Selection.cpp ├── Shell-Sort(Shell's-Gap-Sequence).cpp ├── Sieve-of-Eratosthenes.cpp ├── Singly-Linked-List(Pointer).cpp ├── Skip-List.cpp ├── Sparse-Table.cpp ├── Splay(Single-Rotation).cpp ├── Splay-with-Parent(Array).cpp ├── Splay.cpp ├── Sprague-Grundy.cpp ├── Stack.cpp ├── Stirling-Number(Cycle,Unsigned,Recursion).cpp ├── Stirling-Number(Subset,Recursion).cpp ├── Suffix-Array(Doubling).cpp ├── Suffix-Array-with-Height(Doubling).cpp ├── Suffix-Automaton.cpp ├── Tarjan(Strongly-Connected-Components).cpp ├── Treap.cpp ├── Trie(Array).cpp ├── Trie(Pointer).cpp ├── license.md └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | a.out 3 | -------------------------------------------------------------------------------- /2-Satisfiability.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct vertex 6 | { 7 | int first, dfn, low, col; 8 | }V[2010]; 9 | 10 | struct edge 11 | { 12 | int endp, next; 13 | }E[4000000]; 14 | 15 | int ivc, iec, ec = 1, dfn = 1, col = 1, S[2010], sp = 0; 16 | bool ins[2010]; 17 | 18 | inline int min(int x, int y) 19 | { 20 | return x < y ? x : y; 21 | } 22 | 23 | void add_edge(int u, int v) 24 | { 25 | E[ec].next = V[u].first; 26 | V[u].first = ec; 27 | E[ec].endp = v; 28 | ec++; 29 | } 30 | 31 | void DFS(int u) 32 | { 33 | S[sp++] = u; 34 | ins[u] = true; 35 | V[u].dfn = V[u].low = dfn++; 36 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 37 | { 38 | if (V[E[cur].endp].dfn == 0) 39 | { 40 | DFS(E[cur].endp); 41 | } 42 | if (ins[E[cur].endp] == true && V[E[cur].endp].low < V[u].low) 43 | { 44 | V[u].low = V[E[cur].endp].low; 45 | } 46 | } 47 | if (V[u].low == V[u].dfn) 48 | { 49 | int temp; 50 | do 51 | { 52 | temp = S[--sp]; 53 | ins[temp] = false; 54 | V[temp].col = col; 55 | } while (temp != u); 56 | col++; 57 | } 58 | } 59 | 60 | int main() 61 | { 62 | int x, y, c; 63 | char op[10]; 64 | scanf("%d%d", &ivc, &iec); 65 | for (int i = 0; i < iec; i++) 66 | { 67 | scanf("%d%d%d%s", &x, &y, &c, op); 68 | switch (op[0]) 69 | { 70 | case 'A': 71 | if (c == 0) 72 | { 73 | add_edge(x, y + ivc); 74 | add_edge(y, x + ivc); 75 | } 76 | else 77 | { 78 | add_edge(x + ivc, x); 79 | add_edge(y + ivc, y); 80 | } 81 | break; 82 | case 'O': 83 | if (c == 0) 84 | { 85 | add_edge(x, x + ivc); 86 | add_edge(y, y + ivc); 87 | } 88 | else 89 | { 90 | add_edge(x + ivc, y); 91 | add_edge(y + ivc, x); 92 | } 93 | break; 94 | case 'X': 95 | if (c == 0) 96 | { 97 | add_edge(x, y); 98 | add_edge(y, x); 99 | add_edge(x + ivc, y + ivc); 100 | add_edge(y + ivc, x + ivc); 101 | } 102 | else 103 | { 104 | add_edge(x, y + ivc); 105 | add_edge(y, x + ivc); 106 | add_edge(x + ivc, y); 107 | add_edge(y + ivc, x); 108 | } 109 | break; 110 | } 111 | } 112 | for (int i = ivc * 2 - 1; i >= 0; i--) 113 | { 114 | if (V[i].dfn == 0) 115 | { 116 | DFS(i); 117 | } 118 | } 119 | for (int i = 0; i < ivc; i++) 120 | { 121 | if (V[i].col == V[i + ivc].col) 122 | { 123 | printf("NO"); 124 | return 0; 125 | } 126 | } 127 | printf("YES"); 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /Aho-Corasick-Automaton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define NIL 0 6 | #define ALPHABET_SIZE 26 7 | #define STRING_LENGTH 100000 8 | #define PATTERN_COUNT 1000 9 | #define PATTERN_LENGTH 1000 10 | #define NODE_COUNT 100000 11 | 12 | using namespace std; 13 | 14 | struct node 15 | { 16 | int id; 17 | node *next[ALPHABET_SIZE], *fail, *last; 18 | node(); 19 | }*root; 20 | 21 | int idc = 0; 22 | char s[PATTERN_COUNT][PATTERN_LENGTH], t[STRING_LENGTH]; 23 | int len[PATTERN_COUNT]; 24 | 25 | node::node() : id(0), fail(NIL), last(NIL) 26 | { 27 | memset(next, 0, sizeof(next)); 28 | } 29 | 30 | void init_trie() 31 | { 32 | root = new node; 33 | } 34 | 35 | void insert(char *s) 36 | { 37 | int l = strlen(s), x; 38 | node *cur = root; 39 | for (int i = 0; i < l; i++) 40 | { 41 | x = s[i] - 'a'; 42 | if (cur->next[x] == NIL) 43 | { 44 | cur->next[x] = new node; 45 | } 46 | cur = cur->next[x]; 47 | } 48 | cur->id = ++idc; 49 | } 50 | 51 | void init_fail() 52 | { 53 | queue Q; 54 | root->fail = root; 55 | root->last = root; 56 | for (int i = 0; i < ALPHABET_SIZE; i++) 57 | { 58 | if (root->next[i] != NIL) 59 | { 60 | root->next[i]->fail = root; 61 | root->next[i]->last = root; 62 | Q.push(root->next[i]); 63 | } 64 | else 65 | { 66 | root->next[i] = root; 67 | } 68 | } 69 | while (!Q.empty()) 70 | { 71 | node *cur = Q.front(); 72 | Q.pop(); 73 | for (int i = 0; i < ALPHABET_SIZE; i++) 74 | { 75 | if (cur->next[i] != NIL) 76 | { 77 | cur->next[i]->fail = cur->fail->next[i]; 78 | cur->next[i]->last = cur->next[i]->fail->id > 0 ? cur->next[i]->fail : cur->next[i]->fail->last; 79 | Q.push(cur->next[i]); 80 | } 81 | else 82 | { 83 | cur->next[i] = cur->fail->next[i]; 84 | } 85 | } 86 | } 87 | } 88 | 89 | void print(node *cur, int shift) 90 | { 91 | while (cur != root) 92 | { 93 | printf("matched with shift %2d : %s\n", shift - len[cur->id] + 1, s[cur->id]); 94 | cur = cur->last; 95 | } 96 | } 97 | 98 | void ac_automation() 99 | { 100 | int l = strlen(t); 101 | node *cur = root; 102 | for (int i = 0; i < l; i++) 103 | { 104 | cur = cur->next[t[i] - 'a']; 105 | if (cur->id > 0) 106 | { 107 | print(cur, i); 108 | } 109 | else 110 | { 111 | print(cur->last, i); 112 | } 113 | } 114 | } 115 | 116 | int main() 117 | { 118 | int n; 119 | scanf("%s", t); 120 | scanf("%d", &n); 121 | init_trie(); 122 | for (int i = 1; i <= n; i++) 123 | { 124 | scanf("%s", s[i]); 125 | len[i] = strlen(s[i]); 126 | insert(s[i]); 127 | } 128 | init_fail(); 129 | ac_automation(); 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /Bellman-Ford(Queue-Optimised).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | 5 | using namespace std; 6 | 7 | struct vertex 8 | { 9 | int first_edge; 10 | int dis; 11 | }V[100010]; 12 | 13 | struct edge 14 | { 15 | int endp, next; 16 | int w; 17 | }E[1000010]; 18 | 19 | int ec = 1; 20 | int ivc, iec; 21 | 22 | int Q[200000]; 23 | int hp = 0, tp = 0; 24 | 25 | void enqueue(int x) 26 | { 27 | Q[tp] = x; 28 | tp++; 29 | tp %= 200000; 30 | } 31 | 32 | int dequeue() 33 | { 34 | int ret = Q[hp]; 35 | hp++; 36 | hp %= 200000; 37 | return ret; 38 | } 39 | 40 | bool empty() 41 | { 42 | return hp == tp; 43 | } 44 | 45 | void add_edge(int u, int v, int w) 46 | { 47 | E[ec].next = V[u].first_edge; 48 | V[u].first_edge = ec; 49 | E[ec].endp = v; 50 | E[ec].w = w; 51 | ec++; 52 | } 53 | 54 | void initial_single_source(int s) 55 | { 56 | for (int i = 1; i <= ivc; i++) 57 | { 58 | V[i].dis = INF; 59 | } 60 | V[s].dis = 0; 61 | } 62 | 63 | void SPFA(int s) 64 | { 65 | initial_single_source(s); 66 | enqueue(s); 67 | while (!empty()) 68 | { 69 | int u = dequeue(); 70 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 71 | { 72 | int newdis = V[u].dis + E[cur].w; 73 | if (newdis < V[E[cur].endp].dis) 74 | { 75 | V[E[cur].endp].dis = newdis; 76 | enqueue(E[cur].endp); 77 | } 78 | } 79 | } 80 | } 81 | 82 | int main() 83 | { 84 | scanf("%d%d", &ivc, &iec); 85 | for (int i = 0; i < iec; i++) 86 | { 87 | int u, v, w; 88 | scanf("%d%d%d", &u, &v, &w); 89 | add_edge(u, v, w); 90 | add_edge(v, u, w); 91 | } 92 | SPFA(1); 93 | printf("%d", V[ivc].dis); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /Bellman-Ford.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define VERTEX_COUNT 10000 5 | #define EDGE_COUNT 10000 6 | 7 | #define INFINITE 1000000000 8 | 9 | struct vertex 10 | { 11 | int first_edge; 12 | 13 | int x, y; 14 | 15 | double shortest; 16 | }V[VERTEX_COUNT]; 17 | 18 | int vc = 1; 19 | 20 | struct edge 21 | { 22 | int endp; 23 | int next; 24 | 25 | double w; 26 | }E[EDGE_COUNT]; 27 | 28 | int ec = 1; 29 | 30 | int ivc, iec; 31 | 32 | int s, t; 33 | 34 | void AddVertex(int x, int y) 35 | { 36 | V[vc].x = x; 37 | V[vc].y = y; 38 | 39 | vc++; 40 | } 41 | 42 | void AddEdge(int u, int v) 43 | { 44 | E[ec].next = V[u].first_edge; 45 | V[u].first_edge = ec; 46 | E[ec].endp = v; 47 | E[ec].w = sqrt((V[u].x - V[v].x) * (V[u].x - V[v].x) + (V[u].y - V[v].y) * (V[u].y - V[v].y)); 48 | 49 | ec++; 50 | } 51 | 52 | // We assume that s is the source and t is the destination. 53 | void InitialSingleSource() 54 | { 55 | V[s].shortest = 0; 56 | 57 | for (int i = 1; i <= ivc; i++) 58 | { 59 | if (i != s) 60 | { 61 | V[i].shortest = INFINITE; 62 | } 63 | } 64 | } 65 | 66 | // The edge (u, v) must exist. 67 | void Relax(int u, int v, double w) 68 | { 69 | if (w + V[u].shortest < V[v].shortest) 70 | { 71 | V[v].shortest = w + V[u].shortest; 72 | } 73 | } 74 | 75 | // The main procedure of "Bellman-Ford" algorithm. 76 | void Bellman_Ford() 77 | { 78 | InitialSingleSource(); 79 | 80 | for (int i = 0; i < ivc - 1; i++) 81 | { 82 | for (int curp = 1; curp <= ivc; curp++) 83 | { 84 | for (int cure = V[curp].first_edge; cure != 0; cure = E[cure].next) 85 | { 86 | Relax(curp, E[cure].endp, E[cure].w); 87 | } 88 | } 89 | } 90 | } 91 | 92 | int main() 93 | { 94 | scanf("%d", &ivc); 95 | 96 | for (int i = 0; i < ivc; i++) 97 | { 98 | int x, y; 99 | 100 | scanf("%d%d", &x, &y); 101 | 102 | AddVertex(x, y); 103 | } 104 | 105 | scanf("%d", &iec); 106 | 107 | for (int i = 0; i < iec; i++) 108 | { 109 | int u, v; 110 | 111 | scanf("%d%d", &u, &v); 112 | 113 | AddEdge(u, v); 114 | AddEdge(v, u); 115 | } 116 | 117 | scanf("%d%d", &s, &t); 118 | 119 | Bellman_Ford(); 120 | 121 | printf("%.2lf", V[t].shortest); 122 | 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /Biconnected-Component.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define VERTEX_COUNT 100000 4 | #define EDGE_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct vertex 9 | { 10 | int first, dfn, low; 11 | }V[VERTEX_COUNT]; 12 | 13 | struct edge 14 | { 15 | int endp, next, col; 16 | }E[EDGE_COUNT]; 17 | 18 | int ec = 2, ivc, iec, S[VERTEX_COUNT], sp = 0, dfn = 1, col = 1; 19 | 20 | inline int min(int x, int y) 21 | { 22 | return x < y ? x : y; 23 | } 24 | 25 | inline void push(int e) 26 | { 27 | S[sp++] = e; 28 | } 29 | 30 | inline int pop() 31 | { 32 | return S[--sp]; 33 | } 34 | 35 | void add_edge(int u, int v) 36 | { 37 | E[ec].next = V[u].first; 38 | V[u].first = ec; 39 | E[ec].endp = v; 40 | ec++; 41 | } 42 | 43 | void DFS(int u, int p) 44 | { 45 | V[u].dfn = V[u].low = dfn++; 46 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 47 | { 48 | if (V[E[cur].endp].dfn == 0) 49 | { 50 | push(cur); 51 | DFS(E[cur].endp, u); 52 | V[u].low = min(V[u].low, V[E[cur].endp].low); 53 | if (V[E[cur].endp].low >= V[u].dfn) 54 | { 55 | int e; 56 | do 57 | { 58 | e = pop(); 59 | E[e].col = col; 60 | E[e ^ 1].col = col; 61 | } while (e != cur); 62 | col++; 63 | } 64 | } 65 | else if (E[cur].endp != p) 66 | { 67 | push(cur); 68 | V[u].low = min(V[u].low, V[E[cur].endp].dfn); 69 | } 70 | } 71 | } 72 | 73 | int main() 74 | { 75 | int u, v; 76 | scanf("%d%d", &ivc, &iec); 77 | for (int i = 0; i < iec; i++) 78 | { 79 | scanf("%d%d", &u, &v); 80 | add_edge(u, v); 81 | add_edge(v, u); 82 | } 83 | DFS(1, 0); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /Bigraph-Matching(Edmonds-Karp).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | 5 | #define VERTEX_COUNT 10000 6 | #define EDGE_COUNT 100000 7 | 8 | using namespace std; 9 | 10 | struct vertex 11 | { 12 | int first, prev, pree, maxflow; 13 | bool inq; 14 | }V[VERTEX_COUNT]; 15 | 16 | struct edge 17 | { 18 | int endp, next, flow; 19 | }E[EDGE_COUNT]; 20 | 21 | int ec = 2, n, m, ans; 22 | int Q[VERTEX_COUNT], hp = 0, tp = 0; 23 | 24 | void enqueue(int x) 25 | { 26 | Q[tp++] = x; 27 | tp %= VERTEX_COUNT; 28 | } 29 | 30 | int dequeue() 31 | { 32 | hp %= VERTEX_COUNT; 33 | return Q[hp++]; 34 | } 35 | 36 | void add_edge(int u, int v) 37 | { 38 | E[ec].next = V[u].first; 39 | V[u].first = ec; 40 | E[ec].endp = v; 41 | E[ec].flow = 1; 42 | ec++; 43 | E[ec].next = V[v].first; 44 | V[v].first = ec; 45 | E[ec].endp = u; 46 | E[ec].flow = 0; 47 | ec++; 48 | } 49 | 50 | void Edmonds_Karp(int s, int t) 51 | { 52 | bool has_ap = false; 53 | do 54 | { 55 | has_ap = false; 56 | for (int i = 1; i < 10000; i++) 57 | { 58 | V[i].inq = false; 59 | } 60 | hp = tp = 0; 61 | enqueue(s); 62 | V[s].inq = true; 63 | while (hp != tp) 64 | { 65 | int u = dequeue(); 66 | if (u == t) 67 | { 68 | int x = u, apflow = INF; 69 | while (x != s) 70 | { 71 | if (E[V[x].pree].flow < apflow) 72 | { 73 | apflow = E[V[x].pree].flow; 74 | } 75 | x = V[x].prev; 76 | } 77 | ans += apflow; 78 | x = u; 79 | while (x != s) 80 | { 81 | E[V[x].pree].flow -= apflow; 82 | E[V[x].pree ^ 1].flow += apflow; 83 | x = V[x].prev; 84 | } 85 | has_ap = true; 86 | break; 87 | } 88 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 89 | { 90 | if (V[E[cur].endp].inq == false && E[cur].flow > 0) 91 | { 92 | enqueue(E[cur].endp); 93 | V[E[cur].endp].inq = true; 94 | V[E[cur].endp].prev = u; 95 | V[E[cur].endp].pree = cur; 96 | } 97 | } 98 | } 99 | } while (has_ap == true); 100 | } 101 | 102 | int main() 103 | { 104 | int k, u; 105 | scanf("%d", &n); 106 | for (int i = 1; i <= n; i++) 107 | { 108 | scanf("%d", &k); 109 | for (int j = 0; j < k; j++) 110 | { 111 | scanf("%d", &u); 112 | add_edge(i, u + 1000); 113 | } 114 | } 115 | scanf("%d", &m); 116 | for (int i = 0; i < m; i++) 117 | { 118 | scanf("%d", &u); 119 | add_edge(u + 1000, 9999); 120 | } 121 | for (int i = 1; i <= n; i++) 122 | { 123 | add_edge(9998, i); 124 | } 125 | Edmonds_Karp(9998, 9999); 126 | printf("%d", ans); 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /Bigraph-Matching(Improved-Shortest-Augmenting-Path).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | 5 | using namespace std; 6 | 7 | struct vertex 8 | { 9 | int first, dis; 10 | }V[1010]; 11 | 12 | struct edge 13 | { 14 | int endp, next, flow; 15 | }E[502010]; 16 | 17 | int nl, nr, iec, ec = 2, src = 1005, sink = 1006, gap[1010]; 18 | 19 | inline int min(int x, int y) 20 | { 21 | return x < y ? x : y; 22 | } 23 | 24 | void init() 25 | { 26 | gap[0] = nl + nr + 2; 27 | } 28 | 29 | void add_edge(int u, int v, int f) 30 | { 31 | E[ec].next = V[u].first; 32 | V[u].first = ec; 33 | E[ec].endp = v; 34 | E[ec].flow = f; 35 | ec++; 36 | } 37 | 38 | int isap(int u, int curf) 39 | { 40 | if (u == sink) 41 | { 42 | return curf; 43 | } 44 | int totalf = 0, mindis = nl + nr + 2; 45 | for (int cur = V[u].first; cur != 0 && totalf < curf; cur = E[cur].next) 46 | { 47 | if (E[cur].flow > 0) 48 | { 49 | if (V[u].dis == V[E[cur].endp].dis + 1) 50 | { 51 | int f = isap(E[cur].endp, min(curf - totalf, E[cur].flow)); 52 | E[cur].flow -= f; 53 | E[cur ^ 1].flow += f; 54 | totalf += f; 55 | } 56 | if (V[E[cur].endp].dis < mindis) 57 | { 58 | mindis = V[E[cur].endp].dis; 59 | } 60 | } 61 | } 62 | if (totalf == 0) 63 | { 64 | if (--gap[V[u].dis] == 0) V[src].dis = nl + nr + 2; 65 | V[u].dis = mindis + 1; 66 | gap[V[u].dis]++; 67 | } 68 | return totalf; 69 | } 70 | 71 | int max_flow() 72 | { 73 | int res = 0; 74 | while (V[src].dis < nl + nr + 2) 75 | { 76 | res += isap(src, INF); 77 | } 78 | return res; 79 | } 80 | 81 | int main() 82 | { 83 | int u, v; 84 | scanf("%d%d%d", &nl, &nr, &iec); 85 | for (int i = 0; i < iec; i++) 86 | { 87 | scanf("%d%d", &u, &v); 88 | add_edge(u, v + nl, 1); 89 | add_edge(v + nl, u, 0); 90 | } 91 | for (int i = 1; i <= nl; i++) 92 | { 93 | add_edge(src, i, 1); 94 | add_edge(i, src, 0); 95 | } 96 | for (int i = 1; i <= nr; i++) 97 | { 98 | add_edge(i + nl, sink, 1); 99 | add_edge(sink, i + nl, 0); 100 | } 101 | init(); 102 | printf("%d\n", max_flow()); 103 | for (int i = 1; i <= nl; i++) 104 | { 105 | bool has = false; 106 | for (int cur = V[i].first; cur != 0; cur = E[cur].next) 107 | { 108 | if (E[cur].endp != src && E[cur].flow == 0) 109 | { 110 | printf("%d ", E[cur].endp - nl); 111 | has = true; 112 | break; 113 | } 114 | } 115 | if (has == false) 116 | { 117 | printf("0 "); 118 | } 119 | } 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /Binary-Search-Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define TREE_SIZE 100000 4 | 5 | using namespace std; 6 | 7 | struct node 8 | { 9 | int lch, rch, key, satellite; 10 | }T[TREE_SIZE]; 11 | 12 | int tc = 1; 13 | 14 | int _satellite; 15 | void insert(int rt, int x) 16 | { 17 | if (T[rt].lch == 0 && T[rt].rch == 0) 18 | { 19 | T[rt].lch = tc++; 20 | T[rt].rch = tc++; 21 | T[rt].key = x; 22 | T[rt].satellite = _satellite; 23 | } 24 | else 25 | { 26 | if (x < T[rt].key) 27 | { 28 | insert(T[rt].lch, x); 29 | } 30 | else 31 | { 32 | insert(T[rt].rch, x); 33 | } 34 | } 35 | } 36 | 37 | int query(int rt, int key) 38 | { 39 | if (T[rt].key == key) 40 | { 41 | return T[rt].satellite; 42 | } 43 | else 44 | { 45 | return key < T[rt].key ? query(T[rt].lch, key) : query(T[rt].rch, key); 46 | } 47 | } 48 | 49 | int main() 50 | { 51 | int ord, key, sat; 52 | while (true) 53 | { 54 | scanf("%d", &ord); 55 | if (ord == 1) 56 | { 57 | scanf("%d%d", &key, &sat); 58 | _satellite = sat; 59 | insert(0, key); 60 | } 61 | else if (ord == 2) 62 | { 63 | scanf("%d", &key); 64 | printf("%d\n", query(0, key)); 65 | } 66 | } 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Breadth-First-Search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define VERTEX_COUNT 100000 4 | #define EDGE_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct vertex 9 | { 10 | int first_edge; 11 | bool vis; 12 | }V[VERTEX_COUNT]; 13 | 14 | struct edge 15 | { 16 | int endp, next; 17 | }E[EDGE_COUNT]; 18 | 19 | int ec = 1; 20 | 21 | int Q[VERTEX_COUNT]; 22 | int hp = 0, tp = 0; 23 | 24 | void enqueue(int x) 25 | { 26 | Q[tp++] = x; 27 | } 28 | 29 | int dequeue() 30 | { 31 | return Q[hp++]; 32 | } 33 | 34 | bool queue_empty() 35 | { 36 | return hp == tp; 37 | } 38 | 39 | void add_edge(int u, int v) 40 | { 41 | E[ec].next = V[u].first_edge; 42 | V[u].first_edge = ec; 43 | E[ec].endp = v; 44 | ec++; 45 | } 46 | 47 | void BFS() 48 | { 49 | while (!queue_empty()) 50 | { 51 | int u = dequeue(); 52 | 53 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 54 | { 55 | if (V[E[cur].endp].vis == false) 56 | { 57 | V[E[cur].endp].vis = true; 58 | enqueue(E[cur].endp); 59 | } 60 | } 61 | } 62 | } 63 | 64 | int main() 65 | { 66 | int ivc, iec; 67 | scanf("%d%d", &ivc, &iec); 68 | 69 | for (int i = 0; i < iec; i++) 70 | { 71 | int u, v; 72 | scanf("%d%d", &u, &v); 73 | 74 | add_edge(u, v); 75 | } 76 | 77 | enqueue(1); 78 | 79 | BFS(); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /Bubble-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int data[1000]; 7 | 8 | void bubble_sort(int *d, int n) 9 | { 10 | for (int k = 1; k < n; k++) 11 | { 12 | for (int i = 1; i < n; i++) 13 | { 14 | if (d[i] < d[i - 1]) 15 | { 16 | int temp = d[i]; 17 | d[i] = d[i - 1]; 18 | d[i - 1] = temp; 19 | } 20 | } 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | for (int i = 0; i < 1000; i++) 27 | { 28 | data[i] = rand(); 29 | } 30 | 31 | bubble_sort(data, 1000); 32 | 33 | for (int i = 0; i < 1000; i++) 34 | { 35 | printf("%d\n", data[i]); 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Bucket-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define INF INT_MAX 5 | 6 | #define ELEMENT_COUNT 100000 7 | #define ELEMENT_RANGE (1 << 17) 8 | #define GROUP_RANGE (1 << 2) 9 | 10 | using namespace std; 11 | 12 | int n, d[ELEMENT_COUNT]; 13 | 14 | struct node 15 | { 16 | int v, next; 17 | }A[ELEMENT_COUNT + 1]; 18 | int head[ELEMENT_RANGE / GROUP_RANGE], cnt[ELEMENT_RANGE / GROUP_RANGE], vc = 1; 19 | 20 | void insert(int v) 21 | { 22 | int group = v / GROUP_RANGE; 23 | A[vc].next = head[group]; 24 | head[group] = vc; 25 | A[vc].v = v; 26 | cnt[group]++; 27 | vc++; 28 | } 29 | 30 | void bucket_sort() 31 | { 32 | for (int i = 0; i < n; i++) 33 | { 34 | insert(d[i]); 35 | } 36 | int ptr = 0; 37 | for (int i = 0; i < ELEMENT_RANGE / GROUP_RANGE; i++) 38 | { 39 | for (int j = 0; j < cnt[i]; j++) 40 | { 41 | int minv = INF, ord; 42 | for (int cur = head[i]; cur != 0; cur = A[cur].next) 43 | { 44 | if (A[cur].v < minv) 45 | { 46 | minv = A[cur].v; 47 | ord = cur; 48 | } 49 | } 50 | d[ptr++] = minv; 51 | A[ord].v = INF; 52 | } 53 | } 54 | } 55 | 56 | int main() 57 | { 58 | scanf("%d", &n); 59 | for (int i = 0; i < n; i++) 60 | { 61 | scanf("%d", &d[i]); 62 | } 63 | bucket_sort(); 64 | for (int i = 0; i < n; i++) 65 | { 66 | printf("%d ", d[i]); 67 | } 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Cartesian-Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define NIL 0 6 | 7 | using namespace std; 8 | 9 | struct data 10 | { 11 | char id[100]; 12 | int pr; 13 | }d[50010]; 14 | 15 | int n, lch[50010], rch[50010], S[50010], sp; 16 | 17 | inline void parse(char *buf, char *str, int *num) 18 | { 19 | for (int i = 0; ; i++) 20 | { 21 | if (buf[i] == '/') 22 | { 23 | buf[i] = ' '; 24 | break; 25 | } 26 | } 27 | sscanf(buf, "%s %d", str, num); 28 | } 29 | 30 | void print_tree(int rt) 31 | { 32 | if (rt != 0) 33 | { 34 | printf("("); 35 | print_tree(lch[rt]); 36 | printf("%s/%d", d[rt].id, d[rt].pr); 37 | print_tree(rch[rt]); 38 | printf(")"); 39 | } 40 | } 41 | 42 | inline bool _data_cmp_(const data &x, const data &y) 43 | { 44 | return strcmp(x.id, y.id) < 0; 45 | } 46 | 47 | int main() 48 | { 49 | char temp[1000]; 50 | while (true) 51 | { 52 | scanf("%d", &n); 53 | if (n == 0) 54 | { 55 | break; 56 | } 57 | for (int i = 1; i <= n; i++) 58 | { 59 | scanf("%s", temp); 60 | parse(temp, d[i].id, &d[i].pr); 61 | } 62 | sort(d + 1, d + n + 1, _data_cmp_); 63 | sp = 0; 64 | for (int i = 1; i <= n; i++) 65 | { 66 | lch[i] = rch[i] = NIL; 67 | S[sp] = 0; 68 | while (sp > 0 && d[i].pr > d[S[sp - 1]].pr) sp--; 69 | if (sp > 0) 70 | { 71 | rch[S[sp - 1]] = i; 72 | } 73 | lch[i] = S[sp]; 74 | S[sp++] = i; 75 | } 76 | print_tree(S[0]); 77 | printf("\n"); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /Centre-of-Gravity(Polygon).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct point 6 | { 7 | double x, y; 8 | point(double _x = 0, double _y = 0) : x(_x), y(_y) { } 9 | }d[1000010]; 10 | 11 | int t, n; 12 | 13 | inline double abs(double x) 14 | { 15 | return x < 0 ? -x : x; 16 | } 17 | 18 | inline point operator - (const point &a, const point &b) 19 | { 20 | return point(a.x - b.x, a.y - b.y); 21 | } 22 | 23 | inline double cross(const point &a, const point &b) 24 | { 25 | return a.x * b.y - a.y * b.x; 26 | } 27 | 28 | inline double area(const point &a, const point &b, const point &c) 29 | { 30 | return cross(b - a, c - a) / 2.0; 31 | } 32 | 33 | int main() 34 | { 35 | scanf("%d", &t); 36 | while (t--) 37 | { 38 | scanf("%d", &n); 39 | for (int i = 0; i < n; i++) 40 | { 41 | scanf("%lf%lf", &d[i].x, &d[i].y); 42 | } 43 | double sumx = 0, sumy = 0, areasum = 0; 44 | for (int i = 2; i < n; i++) 45 | { 46 | double a = area(d[0], d[i - 1], d[i]); 47 | sumx += (d[0].x + d[i - 1].x + d[i].x) / 3.0f * a; 48 | sumy += (d[0].y + d[i - 1].y + d[i].y) / 3.0f * a; 49 | areasum += a; 50 | } 51 | printf("%.2lf %.2lf\n", sumx / areasum + 1e-8, sumy / areasum + 1e-8); 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Combination(Recursion).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MOD 1000000000 4 | #define MAX 1000 5 | 6 | int C[MAX][MAX]; 7 | 8 | void init_C() 9 | { 10 | for (int i = 0; i < MAX; i++) 11 | { 12 | C[i][0] = 1; 13 | } 14 | for (int i = 1; i < MAX; i++) 15 | { 16 | for (int j = 1; j <= i; j++) 17 | { 18 | C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD; 19 | } 20 | } 21 | } 22 | 23 | int main() 24 | { 25 | int n, m; 26 | init_C(); 27 | while (scanf("%d%d", &n, &m) > 0) 28 | { 29 | printf("%d\n", C[n][m]); 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Combination.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int sc, rc; 6 | bool sel[50010]; 7 | 8 | // Take m stone(s) last n stone(s). 9 | void enum_combination(int n, int m) 10 | { 11 | if (m == 0) 12 | { 13 | for (int i = 0; i < sc; i++) 14 | { 15 | if (sel[i]) 16 | { 17 | printf("%d ", i); 18 | } 19 | } 20 | printf("\n"); 21 | return; 22 | } 23 | 24 | if (n > m) 25 | { 26 | sel[sc - n - 1] = true; 27 | enum_combination(n - 1, m - 1); 28 | sel[sc - n - 1] = false; 29 | enum_combination(n - 1, m); 30 | } 31 | else 32 | { 33 | sel[sc - n - 1] = true; 34 | enum_combination(n - 1, m - 1); 35 | } 36 | sel[sc - n - 1] = false; 37 | } 38 | 39 | int main() 40 | { 41 | scanf("%d%d", &sc, &rc); 42 | sc += 2; 43 | enum_combination(sc - 2, rc); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Complex-Number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct complex 6 | { 7 | double re, im; 8 | complex(double _re = 0, double _im = 0) : re(_re), im(_im) { } 9 | }; 10 | 11 | complex operator + (const complex &x, const complex &y) 12 | { 13 | return complex(x.re + y.re, x.im + y.im); 14 | } 15 | 16 | complex operator - (const complex &x, const complex &y) 17 | { 18 | return complex(x.re - y.re, x.im - y.im); 19 | } 20 | 21 | complex operator * (const complex &x, const complex &y) 22 | { 23 | return complex(x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re); 24 | } 25 | 26 | complex operator / (const complex &x, const complex &y) 27 | { 28 | return complex((x.re * y.re + x.im * y.im) / (y.re * y.re + y.im * y.im), (x.im * y.re - x.re * y.im) / (y.re * y.re + y.im * y.im)); 29 | } 30 | 31 | int main() 32 | { 33 | complex x, y, res; 34 | char op; 35 | while (true) 36 | { 37 | scanf("%lf%lf %c %lf%lf", &x.re, &x.im, &op, &y.re, &y.im); 38 | switch (op) 39 | { 40 | case '+': 41 | res = x + y; 42 | break; 43 | case '-': 44 | res = x - y; 45 | break; 46 | case '*': 47 | res = x * y; 48 | break; 49 | case '/': 50 | res = x / y; 51 | break; 52 | default: 53 | continue; 54 | } 55 | printf("(%.2lf + (%.2lf)i) %c (%.2lf + (%.2lf)i) = %.2lf + (%.2lf)i\n", x.re, x.im, op, y.re, y.im, res.re, res.im); 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Cut-Vertex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define VERTEX_COUNT 100000 4 | #define EDGE_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct vertex 9 | { 10 | int first, dfn, low; 11 | bool iscv; 12 | }V[VERTEX_COUNT]; 13 | 14 | struct edge 15 | { 16 | int endp, next; 17 | }E[EDGE_COUNT]; 18 | 19 | int ec = 1, ivc, iec, dfn = 1; 20 | 21 | inline int min(int x, int y) 22 | { 23 | return x < y ? x : y; 24 | } 25 | 26 | void add_edge(int u, int v) 27 | { 28 | E[ec].next = V[u].first; 29 | V[u].first = ec; 30 | E[ec].endp = v; 31 | ec++; 32 | } 33 | 34 | void DFS(int u, int p) 35 | { 36 | V[u].dfn = V[u].low = dfn++; 37 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 38 | { 39 | if (V[E[cur].endp].dfn == 0) 40 | { 41 | DFS(E[cur].endp, u); 42 | V[u].low = min(V[u].low, V[E[cur].endp].low); 43 | if (V[E[cur].endp].low >= V[u].dfn) 44 | { 45 | V[u].iscv = true; 46 | } 47 | } 48 | else if (E[cur].endp != p) 49 | { 50 | V[u].low = min(V[u].low, V[E[cur].endp].dfn); 51 | } 52 | } 53 | } 54 | 55 | void get(int rt) 56 | { 57 | int ctc = 0; 58 | V[rt].dfn = V[rt].low = dfn++; 59 | for (int cur = V[rt].first; cur != 0; cur = E[cur].next) 60 | { 61 | if (V[E[cur].endp].dfn == 0) 62 | { 63 | ctc++; 64 | DFS(E[cur].endp, rt); 65 | } 66 | } 67 | if (ctc > 1) 68 | { 69 | V[rt].iscv = true; 70 | } 71 | } 72 | 73 | int main() 74 | { 75 | int u, v; 76 | scanf("%d%d", &ivc, &iec); 77 | for (int i = 0; i < iec; i++) 78 | { 79 | scanf("%d%d", &u, &v); 80 | add_edge(u, v); 81 | add_edge(v, u); 82 | } 83 | for (int i = 1; i <= ivc; i++) 84 | { 85 | if (V[i].dfn == 0) 86 | { 87 | get(i); 88 | } 89 | } 90 | int cnt = 0; 91 | for (int i = 1; i <= ivc; i++) 92 | { 93 | if (V[i].iscv == true) 94 | { 95 | cnt++; 96 | } 97 | } 98 | printf("%d", cnt); 99 | } 100 | -------------------------------------------------------------------------------- /Depth-First-Search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define VERTEX_COUNT 100000 4 | #define EDGE_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct vertex 9 | { 10 | int first_edge; 11 | int ftime; 12 | }V[VERTEX_COUNT]; 13 | 14 | int latest = 1; 15 | 16 | struct edge 17 | { 18 | int endp, next; 19 | }E[EDGE_COUNT]; 20 | 21 | int ec = 1; 22 | 23 | void add_edge(int u, int v) 24 | { 25 | E[ec].next = V[u].first_edge; 26 | V[u].first_edge = ec; 27 | E[ec].endp = v; 28 | ec++; 29 | } 30 | 31 | void DFS(int u) 32 | { 33 | if (V[u].ftime == 0) 34 | { 35 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 36 | { 37 | DFS(E[cur].endp); 38 | } 39 | 40 | V[u].ftime = latest++; 41 | } 42 | } 43 | 44 | int main() 45 | { 46 | int ivc, iec; 47 | scanf("%d%d", &ivc, &iec); 48 | 49 | for (int i = 0; i < iec; i++) 50 | { 51 | int u, v; 52 | scanf("%d%d", &u, &v); 53 | 54 | add_edge(u, v); 55 | } 56 | 57 | DFS(1); 58 | 59 | for (int i = 1; i <= ivc; i++) 60 | { 61 | printf("%d\n", V[i].ftime); 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Dijkstra(Heap-Optimised).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | 5 | #define VERTEX_COUNT 100010 6 | #define EDGE_COUNT 1000010 7 | 8 | using namespace std; 9 | 10 | struct vertex 11 | { 12 | int first_edge; 13 | int dis, hpos; 14 | }V[VERTEX_COUNT]; 15 | 16 | struct edge 17 | { 18 | int endp, next; 19 | int w; 20 | }E[EDGE_COUNT]; 21 | 22 | int ec = 1; 23 | int ivc, iec; 24 | 25 | int H[VERTEX_COUNT], pos[VERTEX_COUNT]; 26 | int heapsize; 27 | 28 | void add_edge(int u, int v, int w) 29 | { 30 | E[ec].next = V[u].first_edge; 31 | V[u].first_edge = ec; 32 | E[ec].endp = v; 33 | E[ec].w = w; 34 | ec++; 35 | } 36 | 37 | void initial_single_source(int s) 38 | { 39 | for (int i = 1; i <= ivc; i++) 40 | { 41 | V[i].dis = INF; 42 | } 43 | V[s].dis = 0; 44 | } 45 | 46 | void build_heap(int s) 47 | { 48 | heapsize = ivc; 49 | for (int i = 1; i <= ivc; i++) 50 | { 51 | H[i] = i; 52 | pos[i] = i; 53 | } 54 | H[s] = 1; 55 | pos[1] = s; 56 | H[1] = s; 57 | pos[s] = 1; 58 | } 59 | 60 | void heap_sink(int i) 61 | { 62 | int lch = i << 1; 63 | int rch = lch + 1; 64 | int smallest = i; 65 | 66 | if (lch <= heapsize && V[H[lch]].dis < V[H[smallest]].dis) 67 | { 68 | smallest = lch; 69 | } 70 | if (rch <= heapsize && V[H[rch]].dis < V[H[smallest]].dis) 71 | { 72 | smallest = rch; 73 | } 74 | 75 | if (smallest != i) 76 | { 77 | V[H[smallest]].hpos = i; 78 | V[H[i]].hpos = smallest; 79 | int temp = H[i]; 80 | H[i] = H[smallest]; 81 | H[smallest] = temp; 82 | heap_sink(smallest); 83 | } 84 | } 85 | 86 | void heap_float(int i) 87 | { 88 | int p = i >> 1; 89 | while (p >= 1 && V[H[i]].dis < V[H[p]].dis) 90 | { 91 | pos[H[i]] = p; 92 | pos[H[p]] = i; 93 | int temp = H[i]; 94 | H[i] = H[p]; 95 | H[p] = temp; 96 | i = p; 97 | p = i >> 1; 98 | } 99 | } 100 | 101 | int extract_min() 102 | { 103 | int res = H[1]; 104 | H[1] = H[heapsize--]; 105 | pos[H[1]] = 1; 106 | heap_sink(1); 107 | return res; 108 | } 109 | 110 | void Dijkstra(int s) 111 | { 112 | initial_single_source(s); 113 | build_heap(s); 114 | 115 | while (heapsize > 0) 116 | { 117 | int u = extract_min(); 118 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 119 | { 120 | int newpath = V[u].dis + E[cur].w; 121 | if (newpath < V[E[cur].endp].dis) 122 | { 123 | V[E[cur].endp].dis = newpath; 124 | heap_float(pos[E[cur].endp]); 125 | } 126 | } 127 | } 128 | } 129 | 130 | int main() 131 | { 132 | scanf("%d%d", &ivc, &iec); 133 | for (int i = 0; i < iec; i++) 134 | { 135 | int u, v, w; 136 | scanf("%d%d%d", &u, &v, &w); 137 | add_edge(u, v, w); 138 | } 139 | 140 | Dijkstra(1); 141 | 142 | printf("%d", V[ivc].dis); 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /Dinic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define INF 2000000000 6 | #define VERTEX_COUNT 100000 7 | #define EDGE_COUNT 100000 8 | 9 | using namespace std; 10 | 11 | struct vertex 12 | { 13 | int first, dis; 14 | }V[VERTEX_COUNT]; 15 | 16 | struct edge 17 | { 18 | int endp, next, f; 19 | }E[EDGE_COUNT]; 20 | 21 | int ivc, iec, ec = 2, src, sink; 22 | 23 | inline void add_edge(int u, int v, int f) 24 | { 25 | E[ec].next = V[u].first; 26 | V[u].first = ec; 27 | E[ec].endp = v; 28 | E[ec].f = f; 29 | ec++; 30 | } 31 | 32 | bool bfs() 33 | { 34 | queue Q; 35 | static bool inq[VERTEX_COUNT]; 36 | memset(inq, false, sizeof(inq)); 37 | Q.push(sink), inq[sink] = true; 38 | while (!Q.empty()) 39 | { 40 | int u = Q.front(); 41 | Q.pop(); 42 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 43 | { 44 | if (E[cur ^ 1].f > 0 && inq[E[cur].endp] == false) 45 | { 46 | V[E[cur].endp].dis = V[u].dis + 1; 47 | Q.push(E[cur].endp), inq[E[cur].endp] = true; 48 | } 49 | } 50 | } 51 | return inq[src] == true; 52 | } 53 | 54 | int dfs(int u, int curf) 55 | { 56 | if (u == sink) return curf; 57 | int totalf = 0; 58 | for (int cur = V[u].first; cur != 0 && totalf < curf; cur = E[cur].next) 59 | { 60 | if (V[u].dis == V[E[cur].endp].dis + 1 && E[cur].f > 0) 61 | { 62 | int f = dfs(E[cur].endp, min(E[cur].f, curf - totalf)); 63 | E[cur].f -= f; 64 | E[cur ^ 1].f += f; 65 | totalf += f; 66 | } 67 | } 68 | return totalf; 69 | } 70 | 71 | int max_flow() 72 | { 73 | int res = 0; 74 | while (bfs() == true) 75 | { 76 | int flow; 77 | do 78 | { 79 | flow = dfs(src, INF); 80 | res += flow; 81 | } while (flow > 0); 82 | } 83 | return res; 84 | } 85 | 86 | int main() 87 | { 88 | int u, v, f; 89 | scanf("%d%d", &iec, &ivc); 90 | for (int i = 0; i < iec; i++) 91 | { 92 | scanf("%d%d%d", &u, &v, &f); 93 | add_edge(u, v, f); 94 | add_edge(v, u, 0); 95 | } 96 | src = 1, sink = ivc; 97 | printf("%d", max_flow()); 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /Disjoint-Set-Union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_ELEMENT_COUNT 5010 4 | 5 | using namespace std; 6 | 7 | int fa[MAX_ELEMENT_COUNT], size[MAX_ELEMENT_COUNT]; 8 | 9 | int getrt(int v) 10 | { 11 | if (fa[v] == v) 12 | { 13 | return v; 14 | } 15 | return (fa[v] = getrt(fa[v])); 16 | } 17 | 18 | void merge(int x, int y) 19 | { 20 | int rx = getrt(x), ry = getrt(y); 21 | 22 | if (size[rx] < size[ry]) 23 | { 24 | fa[rx] = ry; 25 | size[ry] += size[rx]; 26 | } 27 | else 28 | { 29 | fa[ry] = rx; 30 | size[rx] += size[ry]; 31 | } 32 | } 33 | 34 | void initial(int n) 35 | { 36 | for (int i = 1; i <= n; i++) 37 | { 38 | fa[i] = i; 39 | size[i] = 1; 40 | } 41 | } 42 | 43 | int main() 44 | { 45 | // e.g. CodeVS - 1073. 46 | int n, m, p; 47 | scanf("%d%d%d", &n, &m, &p); 48 | 49 | initial(n); 50 | 51 | for (int i = 0; i < m; i++) 52 | { 53 | int a, b; 54 | scanf("%d%d", &a, &b); 55 | merge(a, b); 56 | } 57 | 58 | for (int i = 0; i < p; i++) 59 | { 60 | int a, b; 61 | scanf("%d%d", &a, &b); 62 | if (getrt(a) == getrt(b)) 63 | { 64 | printf("Yes\n"); 65 | } 66 | else 67 | { 68 | printf("No\n"); 69 | } 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Edmonds-Karp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define VERTEX_COUNT 210 5 | #define EDGE_COUNT 20000 6 | 7 | using namespace std; 8 | 9 | struct vertex 10 | { 11 | int first_edge; 12 | int pree, prev; 13 | }V[VERTEX_COUNT]; 14 | 15 | bool vis[VERTEX_COUNT]; 16 | 17 | struct edge 18 | { 19 | int endp, next; 20 | int flow; 21 | }E[EDGE_COUNT]; 22 | 23 | int ec = 2; 24 | int ivc, iec; 25 | 26 | int maxflow = 0; 27 | 28 | int Q[VERTEX_COUNT]; 29 | int hp = 0, tp = 0; 30 | 31 | inline int min(int x, int y) 32 | { 33 | return x < y ? x : y; 34 | } 35 | 36 | void add_edge(int u, int v, int f) 37 | { 38 | E[ec].next = V[u].first_edge; 39 | V[u].first_edge = ec; 40 | E[ec].endp = v; 41 | E[ec].flow = f; 42 | ec++; 43 | } 44 | 45 | inline void enqueue(int x) 46 | { 47 | Q[tp++] = x; 48 | } 49 | 50 | inline int dequeue() 51 | { 52 | return Q[hp++]; 53 | } 54 | 55 | inline bool isempty() 56 | { 57 | return hp == tp; 58 | } 59 | 60 | inline void empty() 61 | { 62 | hp = tp = 0; 63 | } 64 | 65 | void Edmonds_Karp(int s, int t) 66 | { 67 | bool has_ap; 68 | 69 | do 70 | { 71 | has_ap = false; 72 | memset(vis, false, sizeof(vis)); 73 | empty(); 74 | enqueue(s); 75 | while (!isempty()) 76 | { 77 | int u = dequeue(); 78 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 79 | { 80 | if (E[cur].flow > 0) 81 | { 82 | if (E[cur].endp == t) 83 | { 84 | has_ap = true; 85 | int p = u, pathmin = E[cur].flow; 86 | while (p != 1) 87 | { 88 | pathmin = min(pathmin, E[V[p].pree].flow); 89 | p = V[p].prev; 90 | } 91 | p = u; 92 | E[cur].flow -= pathmin; 93 | E[cur ^ 1].flow += pathmin; 94 | while (p != 1) 95 | { 96 | E[V[p].pree].flow -= pathmin; 97 | E[V[p].pree ^ 1].flow += pathmin; 98 | p = V[p].prev; 99 | } 100 | maxflow += pathmin; 101 | goto END; 102 | } 103 | else if (vis[E[cur].endp] == false) 104 | { 105 | V[E[cur].endp].pree = cur; 106 | V[E[cur].endp].prev = u; 107 | vis[E[cur].endp] = true; 108 | enqueue(E[cur].endp); 109 | } 110 | } 111 | } 112 | } 113 | 114 | END:; 115 | } while (has_ap == true); 116 | } 117 | 118 | int main() 119 | { 120 | // e.g. CodeVS - 1993. 121 | 122 | scanf("%d%d", &iec, &ivc); 123 | for (int i = 0; i < iec; i++) 124 | { 125 | int u, v, f; 126 | scanf("%d%d%d", &u, &v, &f); 127 | add_edge(u, v, f); 128 | add_edge(v, u, 0); 129 | } 130 | 131 | Edmonds_Karp(1, ivc); 132 | 133 | printf("%d", maxflow); 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /Euler's-Totient-Function-Sieve(Linear).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_ELEMENT 100000000 4 | 5 | using namespace std; 6 | 7 | int prime[MAX_ELEMENT], pc, div[MAX_ELEMENT], phi[MAX_ELEMENT]; 8 | 9 | void sieve(int n) 10 | { 11 | phi[1] = 1; 12 | for (int i = 2; i <= n; i++) 13 | { 14 | if (div[i] == 0) 15 | { 16 | prime[pc++] = i; 17 | div[i] = i; 18 | phi[i] = i - 1; 19 | } 20 | for (int j = 0; j < pc; j++) 21 | { 22 | if (i * prime[j] > n) break; 23 | div[i * prime[j]] = prime[j]; 24 | if (i % prime[j] == 0) 25 | { 26 | phi[i * prime[j]] = phi[i] * prime[j]; 27 | break; 28 | } 29 | else 30 | { 31 | phi[i * prime[j]] = phi[i] * (prime[j] - 1); 32 | } 33 | } 34 | } 35 | } 36 | 37 | int main() 38 | { 39 | int n; 40 | scanf("%d", &n); 41 | sieve(n); 42 | for (int i = 1; i <= n; i++) 43 | { 44 | printf("phi(%d) = %d\n", i, phi[i]); 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Euler's-Totient-Function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | long long Euler(long long x) 6 | { 7 | long long prev = 0, res = x; 8 | for (long long i = 2; i * i <= x; i++) 9 | { 10 | if (x % i == 0) 11 | { 12 | if (i != prev) 13 | { 14 | res = res / i * (i - 1); 15 | prev = i; 16 | } 17 | x /= i; 18 | i = 1; 19 | } 20 | } 21 | if (x != 1 && x != prev) 22 | { 23 | res = res / x * (x - 1); 24 | } 25 | return (long long)res; 26 | } 27 | 28 | int main() 29 | { 30 | while (true) 31 | { 32 | long long x; 33 | scanf("%lld", &x); 34 | if (x == 0) 35 | { 36 | break; 37 | } 38 | printf("%lld\n", Euler(x)); 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Eulerian-Tour(Digraph).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | 5 | using namespace std; 6 | 7 | struct vertex 8 | { 9 | int first, ideg, odeg; 10 | bool vis; 11 | }V[100010]; 12 | 13 | struct edge 14 | { 15 | int op, endp, next; 16 | }E[200010]; 17 | 18 | int ec = 1, ivc, iec, cnt = 0; 19 | int path[200010], pc; 20 | 21 | void add_edge(int u, int v) 22 | { 23 | V[u].odeg++; 24 | V[v].ideg++; 25 | E[ec].next = V[u].first; 26 | V[u].first = ec; 27 | E[ec].op = u; 28 | E[ec].endp = v; 29 | ec++; 30 | } 31 | 32 | void del_edge(int ord) 33 | { 34 | V[E[ord].op].first = E[ord].next; 35 | } 36 | 37 | void connect(int u) 38 | { 39 | if (V[u].vis == false) 40 | { 41 | cnt++; 42 | V[u].vis = true; 43 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 44 | { 45 | connect(E[cur].endp); 46 | } 47 | } 48 | } 49 | 50 | void DFS(int u, int start) 51 | { 52 | int first = V[u].first; 53 | del_edge(first); 54 | if (E[first].endp != start) 55 | { 56 | DFS(E[first].endp, start); 57 | } 58 | path[pc++] = first; 59 | while (V[u].first != NIL) 60 | { 61 | DFS(u, u); 62 | } 63 | } 64 | 65 | int main() 66 | { 67 | int k, u, v; 68 | scanf("%d%d%d", &k, &ivc, &iec); 69 | for (int i = 0; i < iec; i++) 70 | { 71 | scanf("%d%d", &u, &v); 72 | add_edge(u, v); 73 | } 74 | for (int i = 1; i <= ivc; i++) 75 | { 76 | if (V[i].ideg != V[i].odeg) 77 | { 78 | printf("NO"); 79 | return 0; 80 | } 81 | if (V[i].ideg == 0) 82 | { 83 | cnt++; 84 | } 85 | } 86 | int vhe; 87 | for (int i = 1; i <= ivc; i++) 88 | { 89 | if (V[i].ideg != 0) 90 | { 91 | connect(i); 92 | vhe = i; 93 | break; 94 | } 95 | } 96 | if (cnt < ivc) 97 | { 98 | printf("NO"); 99 | return 0; 100 | } 101 | printf("YES\n"); 102 | if (iec == 0) 103 | { 104 | return 0; 105 | } 106 | DFS(vhe, vhe); 107 | for (int i = pc - 1; i >= 0; i--) 108 | { 109 | printf("%d ", path[i]); 110 | } 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /Extended-Euclid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int extended_gcd(int a, int b, int &x, int &y) 6 | { 7 | if (b == 0) 8 | { 9 | x = 1; 10 | y = 0; 11 | return a; 12 | } 13 | int _gcd = extended_gcd(b, a % b, x, y); 14 | int temp = x; 15 | x = y; 16 | y = temp - (a / b) * y; 17 | return _gcd; 18 | } 19 | 20 | int main() 21 | { 22 | int a, b, x, y; 23 | while (true) 24 | { 25 | scanf("%d%d", &a, &b); 26 | int gcd = extended_gcd(a, b, x, y); 27 | printf("gcd = %d, x = %d, y = %d.\n", extended_gcd(a, b, x, y), x, y); 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Fast-Exponentiation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | long long m; 6 | 7 | // Calcutate a ^ b % m; 8 | long long qpow(long long a, long long b) 9 | { 10 | if (b == 1) 11 | { 12 | return a; 13 | } 14 | 15 | long long mid = qpow(a, b >> 1); 16 | if ((b & 1) == 0) 17 | { 18 | return mid * mid % m; 19 | } 20 | else 21 | { 22 | return mid * mid % m * a % m; 23 | } 24 | } 25 | 26 | int main() 27 | { 28 | long long a, b; 29 | scanf("%lld%lld%lld", &a, &b, &m); 30 | printf("%lld", qpow(a, b)); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Fast-Fourier-Transform(Iterative).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct complex 7 | { 8 | double re, im; 9 | complex(double _re = 0, double _im = 0) : re(_re), im(_im) { } 10 | complex operator + (const complex &x) { return complex(re + x.re, im + x.im); } 11 | complex operator - (const complex &x) { return complex(re - x.re, im - x.im); } 12 | complex operator * (const complex &x) { return complex(re * x.re - im * x.im, re * x.im + im * x.re); } 13 | }; 14 | 15 | int n, m, N, k; 16 | complex a[1 << 18], b[1 << 18], res_a[1 << 18], res_b[1 << 18]; 17 | 18 | int log2(int x) 19 | { 20 | int res = -1; 21 | while (x > 0) 22 | { 23 | res++; 24 | x >>= 1; 25 | } 26 | return res; 27 | } 28 | 29 | inline int reverse(int x) 30 | { 31 | int res = 0; 32 | for (int i = 0; i <= k; i++) 33 | { 34 | if ((x & (1 << i)) != 0) 35 | { 36 | res |= (1 << (k - i)); 37 | } 38 | } 39 | return res; 40 | } 41 | 42 | void init(complex *a, complex *res) 43 | { 44 | for (int i = 0; i < N; i++) 45 | { 46 | res[reverse(i)] = a[i]; 47 | } 48 | } 49 | 50 | void dft(complex *a, complex *res, int inv) 51 | { 52 | init(a, res); 53 | for (int i = 2; i <= N; i <<= 1) 54 | { 55 | complex w0(cos(M_PI * 2 / i), inv * sin(M_PI * 2 / i)); 56 | for (int j = 0; j < N; j += i) 57 | { 58 | complex w(1, 0); 59 | for (int k = j; k < j + (i >> 1); k++) 60 | { 61 | complex temp = res[k]; 62 | res[k] = temp + res[k + (i >> 1)] * w; 63 | res[k + (i >> 1)] = temp - res[k + (i >> 1)] * w; 64 | w = w * w0; 65 | } 66 | } 67 | } 68 | } 69 | 70 | int main() 71 | { 72 | scanf("%d%d", &n, &m); 73 | for (int i = 0; i <= n; i++) 74 | { 75 | scanf("%lf", &a[i].re); 76 | } 77 | for (int i = 0; i <= m; i++) 78 | { 79 | scanf("%lf", &b[i].re); 80 | } 81 | k = log2(m + n); 82 | N = 1 << (k + 1); 83 | dft(a, res_a, 1); 84 | dft(b, res_b, 1); 85 | for (int i = 0; i < N; i++) 86 | { 87 | a[i] = res_a[i] * res_b[i]; 88 | } 89 | dft(a, res_a, -1); 90 | for (int i = 0; i <= n + m; i++) 91 | { 92 | printf("%d ", (int)((res_a[i].re / N) + 0.5)); 93 | } 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /Fast-Number-Theoretic-Transform.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MOD 998244353 5 | #define ROOT 3 6 | 7 | typedef long long ll; 8 | 9 | using namespace std; 10 | 11 | int n, n0, n1, k; 12 | ll a0[500000], a1[500000]; 13 | 14 | inline void swap(ll &x, ll &y) 15 | { 16 | ll temp = x; 17 | x = y; 18 | y = temp; 19 | } 20 | 21 | ll qpow(ll x, int y) 22 | { 23 | if (y == 1) return x; 24 | ll t = qpow(x, y >> 1); 25 | t = t * t % MOD; 26 | if ((y & 1) == 0) return t; 27 | else return t * x % MOD; 28 | } 29 | 30 | void pre(ll *a) 31 | { 32 | static ll temp[500000]; 33 | memcpy(temp, a, sizeof(temp)); 34 | for (int i = 0; i < n; i++) 35 | { 36 | int x = 0; 37 | for (int p = 0; p < k; p++) 38 | { 39 | if ((i & (1 << p)) != 0) 40 | { 41 | x += (1 << (k - p - 1)); 42 | } 43 | } 44 | a[i] = temp[x]; 45 | } 46 | } 47 | 48 | void dft(ll *a, int rev) 49 | { 50 | ll _g = rev == 1 ? ROOT : qpow(ROOT, MOD - 2); 51 | for (int i = 2; i <= n; i <<= 1) 52 | { 53 | ll gn = qpow(_g, (MOD - 1) / i); 54 | for (int p = 0; p < n; p += i) 55 | { 56 | ll g = 1LL; 57 | for (int q = p; q < p + (i >> 1); q++) 58 | { 59 | ll temp = a[q]; 60 | a[q] = (a[q] + g * a[q + (i >> 1)]) % MOD; 61 | a[q + (i >> 1)] = (temp - g * a[q + (i >> 1)]) % MOD; 62 | g = g * gn % MOD; 63 | } 64 | } 65 | } 66 | } 67 | 68 | inline ll read() 69 | { 70 | char c; 71 | do 72 | { 73 | c = getchar(); 74 | } while (c < '0' || c > '9'); 75 | return (ll)(c - '0'); 76 | } 77 | 78 | int main() 79 | { 80 | scanf("%d%d", &n0, &n1); 81 | for (int i = 0; i <= n0; i++) 82 | { 83 | a0[i] = read(); 84 | } 85 | for (int i = 0; i <= n1; i++) 86 | { 87 | a1[i] = read(); 88 | } 89 | n = n0 + n1; 90 | while (n > 0) 91 | { 92 | k++; 93 | n >>= 1; 94 | } 95 | n = 1 << k; 96 | pre(a0); 97 | pre(a1); 98 | dft(a0, 1); 99 | dft(a1, 1); 100 | for (int i = 0; i < n; i++) 101 | { 102 | a0[i] = a0[i] * a1[i] % MOD; 103 | } 104 | pre(a0); 105 | dft(a0, -1); 106 | ll inv = qpow(n, MOD - 2); 107 | for (int i = 0; i <= n0 + n1; i++) 108 | { 109 | printf("%lld ", (a0[i] * inv % MOD + MOD) % MOD); 110 | } 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /Fenwick-Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LOWBIT(x) ((x) & (-x)) 4 | 5 | #define ELEMENT_COUNT 1050 6 | #define MOD 45679 7 | 8 | using namespace std; 9 | 10 | // Array D must begin with 1. 11 | int D[ELEMENT_COUNT], T[ELEMENT_COUNT]; 12 | 13 | // The size of D; 14 | int n = 1024; 15 | 16 | void build_tree(int c) 17 | { 18 | for (int i = 1; i <= c; i++) 19 | { 20 | for (int j = i - LOWBIT(i) + 1; j <= i; j++) 21 | { 22 | T[i] += D[j]; 23 | } 24 | } 25 | } 26 | 27 | // Return the sum of 1..k. 28 | int get_sum(int k) 29 | { 30 | int res = 0; 31 | while (k > 0) 32 | { 33 | res += T[k]; 34 | k -= LOWBIT(k); 35 | } 36 | return res; 37 | } 38 | 39 | // D[a] += x and update the tree. 40 | void add_one(int a, int x) 41 | { 42 | while (a <= n) 43 | { 44 | T[a] = (T[a] + x) % MOD; 45 | a += LOWBIT(a); 46 | } 47 | } 48 | 49 | int main() 50 | { 51 | // e.g. CodeVS - 3900. 52 | 53 | for (int i = 1; i <= 1024; i++) 54 | { 55 | D[i] = 1; 56 | } 57 | build_tree(1024); 58 | 59 | int m; 60 | scanf("%d", &m); 61 | 62 | for (int i = 0; i < m; i++) 63 | { 64 | int a, b, c; 65 | scanf("%d%d%d", &a, &b, &c); 66 | if (a == 1) 67 | { 68 | int pre = D[b]; 69 | D[b] = D[b] * c % MOD; 70 | add_one(b, D[b] - pre + MOD); 71 | } 72 | else 73 | { 74 | printf("%d\n", ((get_sum(c) - get_sum(b - 1)) % MOD + MOD) % MOD); 75 | } 76 | } 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /Fibonacci-Heap.cpp: -------------------------------------------------------------------------------- 1 | // Algorithm: Fibonacci Heap 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define NIL 0 8 | #define MAX_HEAP_SIZE 100010 9 | 10 | using namespace std; 11 | 12 | class FibonacciHeap 13 | { 14 | private: 15 | struct node 16 | { 17 | node *child, *parent, *left, *right; 18 | int key, degree; 19 | bool mark; 20 | node(int _key) : child(NIL), parent(NIL), left(NIL), right(NIL), key(_key), degree(0), mark(false) { } 21 | }; 22 | 23 | node *min; 24 | size_t heap_size; 25 | 26 | void _M_insert_to(node *v, node *u); 27 | void _M_insert_to_root_list(node *u); 28 | void _M_remove_from_root_list(node *u); 29 | void _M_link(node *v, node *u); 30 | void _M_consolidate(); 31 | 32 | public: 33 | FibonacciHeap(); 34 | void insert(int key); 35 | int extract_min(); 36 | }; 37 | 38 | void FibonacciHeap::_M_insert_to(node *v, node *u) 39 | { 40 | v->right = u->right; 41 | v->left = u; 42 | u->right->left = v; 43 | u->right = v; 44 | } 45 | 46 | void FibonacciHeap::_M_insert_to_root_list(node *u) 47 | { 48 | _M_insert_to(u, min); 49 | } 50 | 51 | void FibonacciHeap::_M_remove_from_root_list(node *u) 52 | { 53 | u->left->right = u->right; 54 | u->right->left = u->left; 55 | } 56 | 57 | void FibonacciHeap::_M_link(node *v, node *u) 58 | { 59 | _M_remove_from_root_list(v); 60 | if (u->child == NIL) 61 | { 62 | u->child = v; 63 | v->parent = u; 64 | v->left = v->right = v; 65 | } 66 | else 67 | { 68 | _M_insert_to(v, u->child); 69 | v->parent = u; 70 | } 71 | } 72 | 73 | void FibonacciHeap::_M_consolidate() 74 | { 75 | static node *root_list[MAX_HEAP_SIZE]; 76 | node *first = min; 77 | node *u = first; 78 | int cnt = 0; 79 | do 80 | { 81 | root_list[cnt++] = u; 82 | u = u->right; 83 | } while (u != first); 84 | node *list[50]; 85 | memset(list, 0, sizeof(list)); 86 | for (int i = 0; i < cnt; i++) 87 | { 88 | node *x = root_list[i]; 89 | while (list[x->degree] != NIL) 90 | { 91 | node *y = list[x->degree]; 92 | if (x->key > y->key) swap(x, y); 93 | _M_link(y, x); 94 | list[x->degree++] = NIL; 95 | } 96 | list[x->degree] = x; 97 | } 98 | min = NIL; 99 | for (int i = 0; i < 50; i++) 100 | { 101 | if (list[i] != NIL) 102 | { 103 | if (min == NIL) 104 | { 105 | min = list[i]; 106 | list[i]->left = list[i]->right = list[i]; 107 | } 108 | else 109 | { 110 | _M_insert_to_root_list(list[i]); 111 | if (list[i]->key < min->key) min = list[i]; 112 | } 113 | } 114 | } 115 | } 116 | 117 | FibonacciHeap::FibonacciHeap() : min(NIL), heap_size(0) { } 118 | 119 | void FibonacciHeap::insert(int key) 120 | { 121 | if (min == NIL) 122 | { 123 | min = new node(key); 124 | min->left = min->right = min; 125 | } 126 | else 127 | { 128 | node *u = new node(key); 129 | _M_insert_to_root_list(u); 130 | if (key < min->key) min = u; 131 | } 132 | heap_size++; 133 | } 134 | 135 | int FibonacciHeap::extract_min() 136 | { 137 | int res = min->key; 138 | if (min != NIL) 139 | { 140 | if (heap_size == 1) 141 | { 142 | min = NIL; 143 | } 144 | else 145 | { 146 | if (min->child != NIL) 147 | { 148 | static node *child_list[MAX_HEAP_SIZE]; 149 | node *first = min->child; 150 | node *u = first; 151 | int cnt = 0; 152 | do 153 | { 154 | child_list[cnt++] = u; 155 | u = u->right; 156 | } while (u != first); 157 | for (int i = 0; i < cnt; i++) 158 | { 159 | _M_insert_to_root_list(child_list[i]); 160 | } 161 | } 162 | _M_remove_from_root_list(min); 163 | min = min->right; 164 | _M_consolidate(); 165 | } 166 | } 167 | heap_size--; 168 | return res; 169 | } 170 | 171 | int main() 172 | { 173 | FibonacciHeap H; 174 | char op[10]; 175 | int x; 176 | while (true) 177 | { 178 | scanf("%s", op); 179 | if (strcmp(op, "push") == 0) 180 | { 181 | scanf("%d", &x); 182 | H.insert(x); 183 | } 184 | else if (strcmp(op, "pop") == 0) 185 | { 186 | printf("%d\n", H.extract_min()); 187 | } 188 | else 189 | { 190 | printf("Command not found.\n"); 191 | } 192 | } 193 | return 0; 194 | } 195 | -------------------------------------------------------------------------------- /Floyd-Warshall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, q; 6 | int w[100][100]; 7 | 8 | inline int min(int x, int y) 9 | { 10 | return x < y ? x : y; 11 | } 12 | 13 | void Floyd_Warshall() 14 | { 15 | for (int k = 0; k < n; k++) 16 | { 17 | for (int i = 0; i < n; i++) 18 | { 19 | for (int j = 0; j < n; j++) 20 | { 21 | w[i][j] = min(w[i][j], w[i][k] + w[k][j]); 22 | } 23 | } 24 | } 25 | } 26 | 27 | int main() 28 | { 29 | scanf("%d", &n); 30 | for (int i = 0; i < n; i++) 31 | { 32 | for (int j = 0; j < n; j++) 33 | { 34 | scanf("%d", &w[i][j]); 35 | } 36 | } 37 | Floyd_Warshall(); 38 | scanf("%d", &q); 39 | for (int i = 0; i < q; i++) 40 | { 41 | int a, b; 42 | scanf("%d%d", &a, &b); 43 | printf("%d\n", w[a - 1][b - 1]); 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Gaussian-Elimination.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n; 6 | double a[15][15], s[15]; 7 | 8 | void gaussian_elimination() 9 | { 10 | for (int i = 0; i < n; i++) 11 | { 12 | for (int j = i + 1; j < n; j++) 13 | { 14 | for (int k = n; k >= i; k--) 15 | { 16 | a[j][k] -= a[i][k] * (a[j][i] / a[i][i]); 17 | } 18 | } 19 | } 20 | for (int i = n - 1; i >= 0; i--) 21 | { 22 | double b = a[i][n]; 23 | for (int j = n - 1; j > i; j--) 24 | { 25 | b -= a[i][j] * s[j]; 26 | } 27 | s[i] = b / a[i][i]; 28 | } 29 | } 30 | 31 | int main() 32 | { 33 | scanf("%d", &n); 34 | for (int i = 0; i < n; i++) 35 | { 36 | for (int j = 0; j < n; j++) 37 | { 38 | scanf("%lf", &a[i][j]); 39 | } 40 | scanf("%lf", &a[i][n]); 41 | } 42 | gaussian_elimination(); 43 | for (int i = 0; i < n; i++) 44 | { 45 | printf("x[%d] = %.2lf\n", i, s[i]); 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Graham-Scan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define POINT_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct point 9 | { 10 | int x, y; 11 | }P[POINT_COUNT]; 12 | 13 | struct segment 14 | { 15 | point begin, end; 16 | }D[POINT_COUNT]; 17 | 18 | int S[POINT_COUNT], sp = 0; 19 | 20 | int n; 21 | 22 | void push(int x) 23 | { 24 | S[sp++] = x; 25 | } 26 | 27 | int pop() 28 | { 29 | return S[--sp]; 30 | } 31 | 32 | int top() 33 | { 34 | return S[sp - 1]; 35 | } 36 | 37 | int subtop() 38 | { 39 | return S[sp - 2]; 40 | } 41 | 42 | int direction(segment &base, segment &s) 43 | { 44 | return (s.end.x - s.begin.x) * (base.end.y - base.begin.y) - (base.end.x - base.begin.x) * (s.end.y - s.begin.y); 45 | } 46 | 47 | double distance(point &x, point &y) 48 | { 49 | return sqrt(pow(x.x - y.x, 2) + pow(x.y - y.y, 2)); 50 | } 51 | 52 | void qsort(int l, int r) 53 | { 54 | if (l < r) 55 | { 56 | segment x = D[r]; 57 | int j = l - 1; 58 | for (int i = l; i <= r; i++) 59 | { 60 | if (direction(x, D[i]) >= 0) 61 | { 62 | j++; 63 | segment temps = D[i]; 64 | D[i] = D[j]; 65 | D[j] = temps; 66 | point tempp = P[i]; 67 | P[i] = P[j]; 68 | P[j] = tempp; 69 | } 70 | } 71 | qsort(l, j - 1); 72 | qsort(j + 1, r); 73 | } 74 | } 75 | 76 | int main() 77 | { 78 | scanf("%d", &n); 79 | for (int i = 0; i < n; i++) 80 | { 81 | scanf("%d%d", &P[i].x, &P[i].y); 82 | } 83 | int p0 = 0; 84 | for (int i = 1; i < n; i++) 85 | { 86 | if (P[i].x < P[p0].x) 87 | { 88 | p0 = i; 89 | } 90 | else if (P[i].x == P[p0].x) 91 | { 92 | if (P[i].y < P[p0].y) 93 | { 94 | p0 = i; 95 | } 96 | } 97 | } 98 | point temp = P[p0]; 99 | P[p0] = P[0]; 100 | P[0] = temp; 101 | for (int i = 1; i < n; i++) 102 | { 103 | D[i].begin = P[0]; 104 | D[i].end = P[i]; 105 | } 106 | qsort(1, n - 1); 107 | push(0); 108 | for (int i = 1; i < n; i++) 109 | { 110 | if (sp >= 2) 111 | { 112 | if (direction(D[i], D[top()]) == 0) 113 | { 114 | if (P[i].x > P[top()].x) 115 | { 116 | pop(); 117 | } 118 | else 119 | { 120 | continue; 121 | } 122 | } 123 | int dir; 124 | do 125 | { 126 | segment base, toward; 127 | base.begin = P[subtop()]; 128 | base.end = P[top()]; 129 | toward.begin = P[top()]; 130 | toward.end = P[i]; 131 | dir = direction(base, toward); 132 | if (dir > 0) 133 | { 134 | pop(); 135 | } 136 | } while (dir > 0); 137 | } 138 | push(i); 139 | } 140 | double res = 0; 141 | for (int i = 1; i < sp; i++) 142 | { 143 | res += distance(P[S[i]], P[S[i - 1]]); 144 | } 145 | res += distance(P[S[sp - 1]], P[0]); 146 | printf("%.1lf", res); 147 | 148 | return 0; 149 | } 150 | -------------------------------------------------------------------------------- /Greatest-Common-Divisor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int gcd(int x, int y) 6 | { 7 | return y == 0 ? x : gcd(y, x % y); 8 | } 9 | 10 | int main() 11 | { 12 | int a, b; 13 | while (true) 14 | { 15 | scanf("%d%d", &a, &b); 16 | printf("%d\n", gcd(a, b)); 17 | } 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Heap-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_HEAP_SIZE 100000 5 | 6 | using namespace std; 7 | 8 | int n, H[MAX_HEAP_SIZE], heapsize; 9 | 10 | void min_heapify(int i) 11 | { 12 | int smallest = i; 13 | int lch = i << 1; 14 | int rch = lch + 1; 15 | 16 | if (lch <= heapsize && H[smallest] > H[lch]) 17 | { 18 | smallest = lch; 19 | } 20 | if (rch <= heapsize && H[smallest] > H[rch]) 21 | { 22 | smallest = rch; 23 | } 24 | 25 | if (smallest != i) 26 | { 27 | int temp = H[smallest]; 28 | H[smallest] = H[i]; 29 | H[i] = temp; 30 | min_heapify(smallest); 31 | } 32 | } 33 | 34 | void build_heap() 35 | { 36 | for (int i = heapsize >> 1; i >= 1; i--) 37 | { 38 | min_heapify(i); 39 | } 40 | } 41 | 42 | int extract_min() 43 | { 44 | int res = H[1]; 45 | H[1] = H[heapsize--]; 46 | min_heapify(1); 47 | return res; 48 | } 49 | 50 | int main() 51 | { 52 | scanf("%d", &n); 53 | heapsize = n; 54 | for (int i = 1; i <= n; i++) 55 | { 56 | scanf("%d", &H[i]); 57 | } 58 | build_heap(); 59 | while (heapsize > 0) 60 | { 61 | printf("%d\n", extract_min()); 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Heavy-Light-Decomposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NIL 0 5 | #define INF 1000000000 6 | #define VERTEX_COUNT 100000 7 | #define EDGE_COUNT 200000 8 | #define POOL_SIZE 200000 9 | 10 | using namespace std; 11 | 12 | struct edge; 13 | struct vertex 14 | { 15 | edge *first; 16 | int w, depth, size, ord; 17 | vertex *p, *heavy, *top; 18 | }*nil, V[VERTEX_COUNT]; 19 | 20 | struct edge 21 | { 22 | edge *next; 23 | vertex *endp; 24 | edge(edge *_next = NIL, vertex *_endp = nil); 25 | void* operator new (size_t); 26 | }E[EDGE_COUNT]; 27 | 28 | edge::edge(edge *_next, vertex *_endp) : next(_next), endp(_endp) { } 29 | 30 | int Etop = 0; 31 | void* edge::operator new (size_t) 32 | { 33 | return E + Etop++; 34 | } 35 | 36 | struct node 37 | { 38 | node *lch, *rch; 39 | int sum, max; 40 | node(); 41 | void* operator new (size_t); 42 | }*root, pool[POOL_SIZE]; 43 | 44 | node::node() : lch(NIL), rch(NIL), sum(0), max(0) { } 45 | 46 | int pooltop = 0; 47 | void* node::operator new (size_t) 48 | { 49 | return pool + pooltop++; 50 | } 51 | 52 | int ivc, m, ord = 0; 53 | vertex *map[VERTEX_COUNT]; 54 | 55 | void add_edge(vertex *u, vertex *v) 56 | { 57 | u->first = new edge(u->first, v); 58 | } 59 | 60 | void DFS1(vertex *u, vertex *p, int depth) 61 | { 62 | vertex *heavy = nil; 63 | u->p = p; 64 | u->depth = depth; 65 | u->size = 1; 66 | for (edge *cur = u->first; cur != NIL; cur = cur->next) 67 | { 68 | if (cur->endp != p) 69 | { 70 | DFS1(cur->endp, u, depth + 1); 71 | u->size += cur->endp->size; 72 | if (cur->endp->size > heavy->size) 73 | { 74 | heavy = cur->endp; 75 | } 76 | } 77 | } 78 | u->heavy = heavy; 79 | } 80 | 81 | void DFS2(vertex *u, vertex *top) 82 | { 83 | u->top = top; 84 | u->ord = ++ord; 85 | map[ord] = u; 86 | if (u->heavy != nil) 87 | { 88 | DFS2(u->heavy, top); 89 | } 90 | for (edge *cur = u->first; cur != NIL; cur = cur->next) 91 | { 92 | if (cur->endp != u->heavy && cur->endp != u->p) 93 | { 94 | DFS2(cur->endp, cur->endp); 95 | } 96 | } 97 | } 98 | 99 | void build(node *&u, int l, int r) 100 | { 101 | u = new node; 102 | if (l == r) 103 | { 104 | u->sum = u->max = map[l]->w; 105 | } 106 | else 107 | { 108 | int mid = (l + r) >> 1; 109 | build(u->lch, l, mid); 110 | build(u->rch, mid + 1, r); 111 | u->sum = u->lch->sum + u->rch->sum; 112 | u->max = max(u->lch->max, u->rch->max); 113 | } 114 | } 115 | 116 | void modify(node *u, int l, int r, int k, int x) 117 | { 118 | if (l == r) 119 | { 120 | u->sum = u->max = x; 121 | } 122 | else 123 | { 124 | int mid = (l + r) >> 1; 125 | if (k <= mid) 126 | { 127 | modify(u->lch, l, mid, k, x); 128 | } 129 | else 130 | { 131 | modify(u->rch, mid + 1, r, k, x); 132 | } 133 | u->sum = u->lch->sum + u->rch->sum; 134 | u->max = max(u->lch->max, u->rch->max); 135 | } 136 | } 137 | 138 | int query_sum(node *u, int l, int r, int ql, int qr) 139 | { 140 | if (l == ql && r == qr) 141 | { 142 | return u->sum; 143 | } 144 | int mid = (l + r) >> 1; 145 | if (qr <= mid) 146 | { 147 | return query_sum(u->lch, l, mid, ql, qr); 148 | } 149 | else if (ql > mid) 150 | { 151 | return query_sum(u->rch, mid + 1, r, ql, qr); 152 | } 153 | else 154 | { 155 | return query_sum(u->lch, l, mid, ql, mid) + query_sum(u->rch, mid + 1, r, mid + 1, qr); 156 | } 157 | } 158 | 159 | int query_max(node *u, int l, int r, int ql, int qr) 160 | { 161 | if (l == ql && r == qr) 162 | { 163 | return u->max; 164 | } 165 | int mid = (l + r) >> 1; 166 | if (qr <= mid) 167 | { 168 | return query_max(u->lch, l, mid, ql, qr); 169 | } 170 | else if (ql > mid) 171 | { 172 | return query_max(u->rch, mid + 1, r, ql, qr); 173 | } 174 | else 175 | { 176 | return max(query_max(u->lch, l, mid, ql, mid), query_max(u->rch, mid + 1, r, mid + 1, qr)); 177 | } 178 | } 179 | 180 | void tmodify(vertex *x, int v) 181 | { 182 | modify(root, 1, ivc, x->ord, v); 183 | } 184 | 185 | int tquery_sum(vertex *x, vertex *y) 186 | { 187 | int res = 0; 188 | vertex *ux, *uy; 189 | while (x->top != y->top) 190 | { 191 | ux = x->top == x ? x->p : x->top; 192 | uy = y->top == y ? y->p : y->top; 193 | if (ux->depth < uy->depth) 194 | { 195 | swap(x, y); 196 | } 197 | if (x->top == x) 198 | { 199 | res += query_sum(root, 1, ivc, x->ord, x->ord); 200 | x = x->p; 201 | } 202 | else 203 | { 204 | res += query_sum(root, 1, ivc, x->top->ord + 1, x->ord); 205 | x = x->top; 206 | } 207 | } 208 | if (x->depth > y->depth) 209 | { 210 | swap(x, y); 211 | } 212 | res += query_sum(root, 1, ivc, x->ord, y->ord); 213 | return res; 214 | } 215 | 216 | int tquery_max(vertex *x, vertex *y) 217 | { 218 | int res = -INF; 219 | vertex *ux, *uy; 220 | while (x->top != y->top) 221 | { 222 | ux = x->top == x ? x->p : x->top; 223 | uy = y->top == y ? y->p : y->top; 224 | if (ux->depth < uy->depth) 225 | { 226 | swap(x, y); 227 | } 228 | if (x->top == x) 229 | { 230 | res = max(res, query_max(root, 1, ivc, x->ord, x->ord)); 231 | x = x->p; 232 | } 233 | else 234 | { 235 | res = max(res, query_max(root, 1, ivc, x->top->ord + 1, x->ord)); 236 | x = x->top; 237 | } 238 | } 239 | if (x->depth > y->depth) 240 | { 241 | swap(x, y); 242 | } 243 | res = max(res, query_max(root, 1, ivc, x->ord, y->ord)); 244 | return res; 245 | } 246 | 247 | int main() 248 | { 249 | int u, v, a, b; 250 | char op[10]; 251 | scanf("%d", &ivc); 252 | for (int i = 1; i < ivc; i++) 253 | { 254 | scanf("%d%d", &u, &v); 255 | add_edge(V + u, V + v); 256 | add_edge(V + v, V + u); 257 | } 258 | for (int i = 1; i <= ivc; i++) 259 | { 260 | scanf("%d", &(V + i)->w); 261 | } 262 | nil = new vertex; 263 | nil->size = 0; 264 | DFS1(V + 1, nil, 1); 265 | DFS2(V + 1, V + 1); 266 | build(root, 1, ivc); 267 | scanf("%d", &m); 268 | while (m--) 269 | { 270 | scanf("%s%d%d", op, &a, &b); 271 | switch (op[1]) 272 | { 273 | case 'H': 274 | tmodify(V + a, b); 275 | break; 276 | case 'S': 277 | printf("%d\n", tquery_sum(V + a, V + b)); 278 | break; 279 | case 'M': 280 | printf("%d\n", tquery_max(V + a, V + b)); 281 | break; 282 | } 283 | } 284 | return 0; 285 | } 286 | -------------------------------------------------------------------------------- /High-Precision(Integer).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int _global_length_; 7 | 8 | class lint 9 | { 10 | private: 11 | int s_length, n_length, *num; 12 | char *temp; 13 | int max(int x, int y); 14 | void clear(); 15 | int nextshort(int offset); 16 | lint mul1(int x, int offset); 17 | 18 | public: 19 | lint(int len = _global_length_); 20 | void read(); 21 | void write(); 22 | lint operator + (lint x); 23 | lint operator - (lint x); 24 | lint operator * (lint x); 25 | bool operator < (lint x); 26 | }; 27 | 28 | int lint::max(int x, int y) 29 | { 30 | return x > y ? x : y; 31 | } 32 | 33 | void lint::clear() 34 | { 35 | memset(num, 0, n_length * sizeof(num[0])); 36 | } 37 | 38 | int lint::nextshort(int offset) 39 | { 40 | int res = 0; 41 | for (int i = max(offset - 3, 0); i <= offset; i++) 42 | { 43 | res = res * 10 + (temp[i] - '0'); 44 | } 45 | return res; 46 | } 47 | 48 | lint lint::mul1(int x, int offset) 49 | { 50 | lint res(s_length); 51 | int d = 0; 52 | for (int i = 0; i + offset < n_length; i++) 53 | { 54 | d = num[i] * x + d; 55 | res.num[i + offset] = d % 10000; 56 | d /= 10000; 57 | } 58 | return res; 59 | } 60 | 61 | lint::lint(int len) 62 | { 63 | s_length = len; 64 | n_length = len / 4; 65 | temp = new char[s_length]; 66 | num = new int[n_length]; 67 | clear(); 68 | } 69 | 70 | void lint::read() 71 | { 72 | scanf("%s", temp); 73 | clear(); 74 | int l = strlen(temp), k = 0; 75 | for (int i = l - 1; i >= 0; i -= 4) 76 | { 77 | num[k++] = nextshort(i); 78 | } 79 | } 80 | 81 | void lint::write() 82 | { 83 | int i; 84 | for (i = n_length - 1; i >= 0; i--) 85 | { 86 | if (num[i] != 0) 87 | { 88 | break; 89 | } 90 | } 91 | if (i == -1) 92 | { 93 | printf("0"); 94 | return; 95 | } 96 | printf("%d", num[i]); 97 | for (i--; i >= 0; i--) 98 | { 99 | printf("%04d", num[i]); 100 | } 101 | } 102 | 103 | lint lint::operator + (lint x) 104 | { 105 | lint res(s_length); 106 | int d = 0; 107 | for (int i = 0; i < n_length; i++) 108 | { 109 | d += num[i] + x.num[i]; 110 | res.num[i] = d % 10000; 111 | d /= 10000; 112 | } 113 | return res; 114 | } 115 | 116 | lint lint::operator - (lint x) 117 | { 118 | lint res(s_length); 119 | int d = 0; 120 | for (int i = 0; i < n_length; i++) 121 | { 122 | d += num[i] - x.num[i]; 123 | res.num[i] = (d + 10000) % 10000; 124 | d = d < 0 ? -1 : 0; 125 | } 126 | return res; 127 | } 128 | 129 | lint lint::operator * (lint x) 130 | { 131 | lint res(s_length), t(s_length); 132 | for (int i = 0; i < s_length; i++) 133 | { 134 | t = mul1(x.num[i], i); 135 | res = res + t; 136 | } 137 | return res; 138 | } 139 | 140 | bool lint::operator < (lint x) 141 | { 142 | for (int i = n_length - 1; i >= 0; i--) 143 | { 144 | if (num[i] < x.num[i]) 145 | { 146 | return true; 147 | } 148 | else if (num[i] > x.num[i]) 149 | { 150 | return false; 151 | } 152 | } 153 | return false; 154 | } 155 | 156 | int main() 157 | { 158 | lint a(100), b(100); 159 | char op[10]; 160 | while (true) 161 | { 162 | a.read(); 163 | scanf("%s", op); 164 | b.read(); 165 | switch (op[0]) 166 | { 167 | case '+': 168 | (a + b).write(); 169 | break; 170 | case '-': 171 | if (a < b) 172 | { 173 | printf("-"); 174 | (b - a).write(); 175 | } 176 | else 177 | { 178 | (a - b).write(); 179 | } 180 | break; 181 | case '*': 182 | (a * b).write(); 183 | break; 184 | default: 185 | printf("Invalid operator."); 186 | break; 187 | } 188 | printf("\n"); 189 | } 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /Hungarian-Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define VERTEX_COUNT 1010 5 | #define EDGE_COUNT 250010 6 | 7 | using namespace std; 8 | 9 | struct vertex 10 | { 11 | int first, mv; 12 | }V[VERTEX_COUNT]; 13 | 14 | struct edge 15 | { 16 | int endp, next; 17 | }E[EDGE_COUNT]; 18 | 19 | int nl, nr, iec, ec = 2; 20 | bool vis[VERTEX_COUNT]; 21 | 22 | inline void add_edge(int u, int v) 23 | { 24 | E[ec].next = V[u].first; 25 | V[u].first = ec; 26 | E[ec].endp = v; 27 | ec++; 28 | } 29 | 30 | bool dfs(int u) 31 | { 32 | if (vis[u] == true) return false; 33 | vis[u] = true; 34 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 35 | { 36 | if (V[u].mv != E[cur].endp && (V[E[cur].endp].mv == 0 || dfs(V[E[cur].endp].mv) == true)) 37 | { 38 | V[u].mv = E[cur].endp; 39 | V[E[cur].endp].mv = u; 40 | return true; 41 | } 42 | } 43 | return false; 44 | } 45 | 46 | int match() 47 | { 48 | int res = 0; 49 | for (int i = 1; i <= nl; i++) 50 | { 51 | memset(vis, false, sizeof(vis)); 52 | res += (int)dfs(i); 53 | } 54 | return res; 55 | } 56 | 57 | int main() 58 | { 59 | int u, v; 60 | scanf("%d%d%d", &nl, &nr, &iec); 61 | for (int i = 0; i < iec; i++) 62 | { 63 | scanf("%d%d", &u, &v); 64 | add_edge(u, v + nl); 65 | } 66 | printf("%d\n", match()); 67 | for (int i = 1; i <= nl; i++) 68 | { 69 | if (V[i].mv != 0) printf("%d ", V[i].mv - nl); 70 | else printf("0 "); 71 | } 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Improved-Shortest-Augmenting-Path(Gap-Optimised).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | #define VERTEX_COUNT 210 5 | #define EDGE_COUNT 410 6 | 7 | using namespace std; 8 | 9 | struct vertex 10 | { 11 | int first, dis; 12 | }V[VERTEX_COUNT]; 13 | 14 | struct edge 15 | { 16 | int endp, next, lower, upper, flow; 17 | }E[EDGE_COUNT]; 18 | 19 | int ivc, iec, ec = 2, gap[VERTEX_COUNT], src, sink; 20 | 21 | inline int min(int x, int y) 22 | { 23 | return x < y ? x : y; 24 | } 25 | 26 | void init() 27 | { 28 | src = 1; 29 | sink = ivc; 30 | gap[0] = ivc; 31 | } 32 | 33 | void add_edge(int u, int v, int lower, int upper, int flow) 34 | { 35 | E[ec].next = V[u].first; 36 | V[u].first = ec; 37 | E[ec].endp = v; 38 | E[ec].lower = lower; 39 | E[ec].upper = upper; 40 | E[ec].flow = flow; 41 | ec++; 42 | } 43 | 44 | int isap(int u, int curf) 45 | { 46 | if (u == sink) 47 | { 48 | return curf; 49 | } 50 | int totalf = 0, mindis = ivc; 51 | for (int cur = V[u].first; cur != 0 && totalf < curf; cur = E[cur].next) 52 | { 53 | if (E[cur].flow > 0) 54 | { 55 | if (V[u].dis == V[E[cur].endp].dis + 1) 56 | { 57 | int f = isap(E[cur].endp, min(E[cur].flow, curf - totalf)); 58 | totalf += f; 59 | E[cur].flow -= f; 60 | E[cur ^ 1].flow += f; 61 | } 62 | mindis = min(mindis, V[E[cur].endp].dis); 63 | } 64 | } 65 | if (totalf == 0) 66 | { 67 | gap[V[u].dis]--; 68 | if (gap[V[u].dis] == 0) V[src].dis = ivc; 69 | V[u].dis = mindis + 1; 70 | gap[V[u].dis]++; 71 | } 72 | return totalf; 73 | } 74 | 75 | int max_flow() 76 | { 77 | int res = 0; 78 | while (V[src].dis < ivc) 79 | { 80 | res += isap(src, INF); 81 | } 82 | return res; 83 | } 84 | 85 | int main() 86 | { 87 | int u, v, f; 88 | scanf("%d%d", &iec, &ivc); 89 | for (int i = 0; i < iec; i++) 90 | { 91 | scanf("%d%d%d", &u, &v, &f); 92 | add_edge(u, v, 0, 0, f); 93 | add_edge(v, u, 0, 0, 0); 94 | } 95 | init(); 96 | printf("%d", max_flow()); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Improved-Shortest-Augmenting-Path(Naive).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | #define VERTEX_COUNT 1000 5 | #define EDGE_COUNT 1000 6 | 7 | using namespace std; 8 | 9 | struct vertex 10 | { 11 | int first, dis; 12 | }V[VERTEX_COUNT]; 13 | 14 | struct edge 15 | { 16 | int endp, next, flow; 17 | }E[EDGE_COUNT]; 18 | 19 | int ec = 2, iec, ivc, src, sink; 20 | 21 | inline int min(int x, int y) 22 | { 23 | return x < y ? x : y; 24 | } 25 | 26 | void add_edge(int u, int v, int f) 27 | { 28 | E[ec].next = V[u].first; 29 | V[u].first = ec; 30 | E[ec].endp = v; 31 | E[ec].flow = f; 32 | ec++; 33 | } 34 | 35 | int DFS(int u, int curf) 36 | { 37 | if (u == sink) 38 | { 39 | return curf; 40 | } 41 | int totalf = 0, mindis = INF; 42 | for (int cur = V[u].first; cur != 0 && totalf < curf; cur = E[cur].next) 43 | { 44 | if (E[cur].flow > 0) 45 | { 46 | if (V[u].dis == V[E[cur].endp].dis + 1) 47 | { 48 | int t = DFS(E[cur].endp, min(curf - totalf, E[cur].flow)); 49 | E[cur].flow -= t; 50 | E[cur ^ 1].flow += t; 51 | totalf += t; 52 | } 53 | mindis = min(mindis, V[E[cur].endp].dis); 54 | } 55 | } 56 | if (totalf == 0) 57 | { 58 | V[u].dis = mindis + 1; 59 | } 60 | return totalf; 61 | } 62 | 63 | int max_flow() 64 | { 65 | int res = 0; 66 | while (V[src].dis < ivc) 67 | { 68 | res += DFS(src, INF); 69 | } 70 | return res; 71 | } 72 | 73 | int main() 74 | { 75 | int u, v, f; 76 | scanf("%d%d", &iec, &ivc); 77 | for (int i = 0; i < iec; i++) 78 | { 79 | scanf("%d%d%d", &u, &v, &f); 80 | add_edge(u, v, f); 81 | add_edge(v, u, 0); 82 | } 83 | src = 1; 84 | sink = ivc; 85 | printf("%d", max_flow()); 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /Insertion-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ELEMENT_COUNT 1000 4 | 5 | using namespace std; 6 | 7 | int n, d[ELEMENT_COUNT]; 8 | 9 | void insertion_sort() 10 | { 11 | for (int i = 1; i < n; i++) 12 | { 13 | for (int j = i; j > 0; j--) 14 | { 15 | if (d[j] < d[j - 1]) 16 | { 17 | int temp = d[j]; 18 | d[j] = d[j - 1]; 19 | d[j - 1] = temp; 20 | } 21 | else 22 | { 23 | break; 24 | } 25 | } 26 | } 27 | } 28 | 29 | int main() 30 | { 31 | scanf("%d", &n); 32 | for (int i = 0; i < n; i++) 33 | { 34 | scanf("%d", &d[i]); 35 | } 36 | insertion_sort(); 37 | for (int i = 0; i < n; i++) 38 | { 39 | printf("%d\n", d[i]); 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /K-Dimensional-Tree.cpp: -------------------------------------------------------------------------------- 1 | // Problem Name: SJY摆棋子 2 | // Algorithm: KD-Tree 3 | 4 | #include 5 | #include 6 | 7 | #define NIL 0 8 | #define INF 1000000000 9 | 10 | using namespace std; 11 | 12 | struct point 13 | { 14 | int co[2]; 15 | point(int x = 0, int y = 0) { co[0] = x, co[1] = y; } 16 | int& operator [] (int x) { return co[x]; } 17 | const int& operator [] (int x) const { return co[x]; } 18 | }d[500010]; 19 | 20 | struct node 21 | { 22 | node *lch, *rch; 23 | point p; 24 | int min[2], max[2]; 25 | node(point _p = point()) : lch(NIL), rch(NIL), p(_p) { /*min[0] = min[1] = INF, max[0] = max[1] = -INF;*/ } 26 | }*root; 27 | 28 | inline int abs(int x) 29 | { 30 | return x < 0 ? -x : x; 31 | } 32 | 33 | inline int dist(point &x, point &y) 34 | { 35 | return abs(x.co[0] - y.co[0]) + abs(x.co[1] - y.co[1]); 36 | } 37 | 38 | int _d_; 39 | inline bool _point_cmp_(const point &x, const point &y) 40 | { 41 | if (x[_d_] == y[_d_]) return x[_d_ ^ 1] < y[_d_ ^ 1]; 42 | return x[_d_] < y[_d_]; 43 | } 44 | 45 | inline void update(node *u) 46 | { 47 | if (u->lch != NIL) 48 | { 49 | u->min[0] = min(u->min[0], u->lch->min[0]); 50 | u->min[1] = min(u->min[1], u->lch->min[1]); 51 | u->max[0] = max(u->max[0], u->lch->max[0]); 52 | u->max[1] = max(u->max[1], u->lch->max[1]); 53 | } 54 | if (u->rch != NIL) 55 | { 56 | u->min[0] = min(u->min[0], u->rch->min[0]); 57 | u->min[1] = min(u->min[1], u->rch->min[1]); 58 | u->max[0] = max(u->max[0], u->rch->max[0]); 59 | u->max[1] = max(u->max[1], u->rch->max[1]); 60 | } 61 | } 62 | 63 | void build(node *&u, int l, int r, int dim) 64 | { 65 | if (l == r) 66 | { 67 | u = new node(d[l]); 68 | u->min[0] = u->max[0] = d[l][0]; 69 | u->min[1] = u->max[1] = d[l][1]; 70 | } 71 | else if (l < r) 72 | { 73 | int mid = (l + r) >> 1; 74 | _d_ = dim; 75 | nth_element(d + l, d + mid, d + r + 1, _point_cmp_); 76 | u = new node(d[mid]); 77 | u->min[0] = u->max[0] = d[mid][0]; 78 | u->min[1] = u->max[1] = d[mid][1]; 79 | build(u->lch, l, mid - 1, dim ^ 1); 80 | build(u->rch, mid + 1, r, dim ^ 1); 81 | update(u); 82 | } 83 | } 84 | 85 | void insert(node *&u, point p, int dim) 86 | { 87 | if (u == NIL) 88 | { 89 | u = new node(p); 90 | u->min[0] = u->max[0] = p[0]; 91 | u->min[1] = u->max[1] = p[1]; 92 | return; 93 | } 94 | if (p[dim] <= u->p[dim]) insert(u->lch, p, dim ^ 1); 95 | else insert(u->rch, p, dim ^ 1); 96 | update(u); 97 | } 98 | 99 | int get_dis(point p, node *u) 100 | { 101 | int res = 0; 102 | if (p[0] < u->min[0]) res += u->min[0] - p[0]; 103 | if (p[0] > u->max[0]) res += p[0] - u->max[0]; 104 | if (p[1] < u->min[1]) res += u->min[1] - p[1]; 105 | if (p[1] > u->max[1]) res += p[1] - u->max[1]; 106 | return res; 107 | } 108 | 109 | int mindis; 110 | void find(node *u, point p, int dim) 111 | { 112 | if (u == NIL) return; 113 | int dis = dist(p, u->p); 114 | if (dis < mindis) mindis = dis; 115 | int dl = INF, dr = INF; 116 | if (u->lch != NIL) dl = get_dis(p, u->lch); 117 | if (u->rch != NIL) dr = get_dis(p, u->rch); 118 | if (dl < dr) 119 | { 120 | if (dl < mindis) find(u->lch, p, dim ^ 1); 121 | if (dr < mindis) find(u->rch, p, dim ^ 1); 122 | } 123 | else 124 | { 125 | if (dr < mindis) find(u->rch, p, dim ^ 1); 126 | if (dl < mindis) find(u->lch, p, dim ^ 1); 127 | } 128 | } 129 | 130 | void dfs(node *u) 131 | { 132 | if (u == NIL) return; 133 | printf("dfs : (%d, %d)\n", u->p[0], u->p[1]); 134 | dfs(u->lch); 135 | dfs(u->rch); 136 | } 137 | 138 | int main() 139 | { 140 | int n, m; 141 | scanf("%d%d", &n, &m); 142 | for (int i = 0; i < n; i++) 143 | { 144 | scanf("%d%d", &d[i][0], &d[i][1]); 145 | } 146 | build(root, 0, n - 1, 0); 147 | int op, x, y; 148 | while (m--) 149 | { 150 | scanf("%d%d%d", &op, &x, &y); 151 | if (op == 1) 152 | { 153 | insert(root, point(x, y), 0); 154 | } 155 | else 156 | { 157 | mindis = INF; 158 | find(root, point(x, y), 0); 159 | if (mindis < INF) printf("%d\n", mindis); 160 | else printf("INF\n"); 161 | } 162 | } 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /Knuth-Morris-Pratt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_LENGTH 100000 5 | 6 | using namespace std; 7 | 8 | char T[MAX_LENGTH], P[MAX_LENGTH]; 9 | int pi[MAX_LENGTH]; 10 | int lt, lp; 11 | 12 | void compute_prefix_function() 13 | { 14 | int q = 0; 15 | pi[0] = 0; 16 | 17 | for (int i = 1; i < lp; i++) 18 | { 19 | while (q > 0 && P[i] != P[q]) 20 | { 21 | q = pi[q - 1]; 22 | } 23 | 24 | if (P[i] == P[q]) 25 | { 26 | q++; 27 | } 28 | 29 | pi[i] = q; 30 | } 31 | } 32 | 33 | void KMP_matcher() 34 | { 35 | compute_prefix_function(); 36 | 37 | int q = 0; 38 | 39 | for (int i = 0; i < lt; i++) 40 | { 41 | while (q > 0 && T[i] != P[q]) 42 | { 43 | q = pi[q - 1]; 44 | } 45 | 46 | if (T[i] == P[q]) 47 | { 48 | q++; 49 | } 50 | 51 | if (q == lp) 52 | { 53 | printf("matched with shift %d\n", i - lp + 1); 54 | q = pi[q - 1]; 55 | } 56 | } 57 | } 58 | 59 | int main() 60 | { 61 | gets(T); 62 | gets(P); 63 | lt = strlen(T); 64 | lp = strlen(P); 65 | 66 | KMP_matcher(); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define VERTEX_COUNT 100000 5 | #define EDGE_COUNT 100000 6 | 7 | typedef long long ll; 8 | 9 | using namespace std; 10 | 11 | struct edge 12 | { 13 | int u, v, w; 14 | }E[EDGE_COUNT]; 15 | 16 | int ivc, iec; 17 | 18 | int fa[VERTEX_COUNT], size[VERTEX_COUNT]; 19 | 20 | bool E_cmp(edge x, edge y) 21 | { 22 | return x.w < y.w; 23 | } 24 | 25 | void init_dsu() 26 | { 27 | for (int i = 1; i <= ivc; i++) 28 | { 29 | fa[i] = i; 30 | size[i] = 1; 31 | } 32 | } 33 | 34 | int getrt(int x) 35 | { 36 | if (fa[x] == x) 37 | { 38 | return x; 39 | } 40 | return (fa[x] = getrt(fa[x])); 41 | } 42 | 43 | void merge(int rtx, int rty) 44 | { 45 | if (size[rtx] < size[rty]) 46 | { 47 | fa[rtx] = rty; 48 | } 49 | else 50 | { 51 | fa[rty] = rtx; 52 | } 53 | } 54 | 55 | ll Kruskal() 56 | { 57 | int cnt = 1; 58 | ll wtotal = 0; 59 | for (int i = 0; i < iec && cnt < ivc; i++) 60 | { 61 | int rtu = getrt(E[i].u), rtv = getrt(E[i].v); 62 | if (rtu != rtv) 63 | { 64 | merge(rtu, rtv); 65 | cnt++; 66 | wtotal += E[i].w; 67 | } 68 | } 69 | return wtotal; 70 | } 71 | 72 | int main() 73 | { 74 | scanf("%d%d", &ivc, &iec); 75 | init_dsu(); 76 | for (int i = 0; i < iec; i++) 77 | { 78 | scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w); 79 | } 80 | sort(E, E + iec, E_cmp); 81 | ll res = Kruskal(); 82 | printf("%lld", res); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Least-Common-Ancestor(Tarjan).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_VERTEX_COUNT 100000 4 | #define MAX_EDGE_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct vertex 9 | { 10 | int first_edge; 11 | bool finish; 12 | }V[MAX_VERTEX_COUNT]; 13 | 14 | struct edge 15 | { 16 | int endp, next; 17 | }E[MAX_EDGE_COUNT]; 18 | 19 | int ec = 1; 20 | 21 | struct qvertex 22 | { 23 | int first_edge; 24 | }QV[MAX_VERTEX_COUNT]; 25 | 26 | struct qedge 27 | { 28 | int endp, next, ans; 29 | }QE[MAX_EDGE_COUNT]; 30 | 31 | int qec = 1; 32 | 33 | int fa[MAX_VERTEX_COUNT], size[MAX_VERTEX_COUNT], ancestor[MAX_VERTEX_COUNT]; 34 | 35 | void add_edge(int u, int v) 36 | { 37 | E[ec].next = V[u].first_edge; 38 | V[u].first_edge = ec; 39 | E[ec].endp = v; 40 | ec++; 41 | } 42 | 43 | void add_qedge(int u, int v) 44 | { 45 | QE[qec].next = QV[u].first_edge; 46 | QV[u].first_edge = qec; 47 | QE[qec].endp = v; 48 | qec++; 49 | } 50 | 51 | void initial_set(int c) 52 | { 53 | for (int i = 1; i <= c; i++) 54 | { 55 | fa[i] = i; 56 | size[i] = 1; 57 | } 58 | } 59 | 60 | int get_root(int x) 61 | { 62 | if (fa[x] == x) 63 | { 64 | return x; 65 | } 66 | return (fa[x] = get_root(fa[x])); 67 | } 68 | 69 | void merge(int x, int y) 70 | { 71 | int rtx = get_root(x), rty = get_root(y); 72 | if (size[rtx] < size[rty]) 73 | { 74 | fa[rtx] = rty; 75 | size[rty] += size[rtx]; 76 | } 77 | else 78 | { 79 | fa[rty] = rtx; 80 | size[rtx] += size[rty]; 81 | } 82 | } 83 | 84 | void DFS(int u, int prev) 85 | { 86 | ancestor[get_root(u)] = u; 87 | 88 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 89 | { 90 | if (E[cur].endp != prev) 91 | { 92 | DFS(E[cur].endp, u); 93 | merge(u, E[cur].endp); 94 | ancestor[get_root(u)] = u; 95 | } 96 | } 97 | V[u].finish = true; 98 | 99 | for (int cur = QV[u].first_edge; cur != 0; cur = QE[cur].next) 100 | { 101 | if (V[QE[cur].endp].finish == true) 102 | { 103 | QE[cur].ans = ancestor[get_root(QE[cur].endp)]; 104 | } 105 | } 106 | } 107 | 108 | int main() 109 | { 110 | int ivc, iqc; 111 | scanf("%d%d", &ivc, &iqc); 112 | 113 | for (int i = 1; i < ivc; i++) 114 | { 115 | int u, v; 116 | scanf("%d%d", &u, &v); 117 | add_edge(u, v); 118 | add_edge(v, u); 119 | } 120 | 121 | for (int i = 0; i < iqc; i++) 122 | { 123 | int u, v; 124 | scanf("%d%d", &u, &v); 125 | add_qedge(u, v); 126 | add_qedge(v, u); 127 | } 128 | 129 | initial_set(ivc); 130 | 131 | DFS(1, 0); 132 | 133 | for (int i = 1; i <= ivc; i++) 134 | { 135 | for (int cur = QV[i].first_edge; cur != 0; cur = QE[cur].next) 136 | { 137 | if (QE[cur].ans != 0) 138 | { 139 | printf("The LCA of %d and %d is %d.\n", i, QE[cur].endp, QE[cur].ans); 140 | } 141 | } 142 | } 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /Leftist-Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct node 6 | { 7 | node *lch, *rch; 8 | int key, dis; 9 | node(int _key = 0, int _dis = 0); 10 | }*root, *nil; 11 | 12 | node::node(int _key, int _dis) : key(_key), dis(_dis) 13 | { 14 | lch = rch = nil; 15 | } 16 | 17 | void init() 18 | { 19 | nil = new node(0, -1); 20 | root = nil; 21 | } 22 | 23 | inline void swap(node *&u, node *&v) 24 | { 25 | node *temp = u; 26 | u = v; 27 | v = temp; 28 | } 29 | 30 | void merge(node *&u, node *&v) 31 | { 32 | if (u == nil) 33 | { 34 | u = v; 35 | return; 36 | } 37 | if (v == nil) return; 38 | if (u->key > v->key) swap(u, v); 39 | merge(u->rch, v); 40 | if (u->lch->dis < u->rch->dis) swap(u->lch, u->rch); 41 | u->dis = u->rch->dis + 1; 42 | } 43 | 44 | int extract_min() 45 | { 46 | int res = root->key; 47 | merge(root->lch, root->rch); 48 | node *del = root; 49 | root = root->lch; 50 | delete del; 51 | return res; 52 | } 53 | 54 | int main() 55 | { 56 | int op, x; 57 | init(); 58 | while (true) 59 | { 60 | scanf("%d", &op); 61 | if (op == 1) 62 | { 63 | scanf("%d", &x); 64 | node *o = new node(x, 0); 65 | merge(root, o); 66 | } 67 | else if (op == 2) 68 | { 69 | printf("%d\n", extract_min()); 70 | } 71 | else if (op == 0) 72 | { 73 | break; 74 | } 75 | else 76 | { 77 | printf("No such command!\n"); 78 | } 79 | } 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /Linear-Basis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, d[100000], b[32], bsize; 6 | 7 | void linear_basis() 8 | { 9 | for (int i = 0; i < n; i++) 10 | { 11 | for (int j = 30; j >= 0 && d[i] != 0; j--) 12 | { 13 | if ((d[i] >> j) == 0) continue; 14 | else if (b[j] != 0) d[i] ^= b[j]; 15 | else 16 | { 17 | b[j] = d[i]; 18 | bsize++; 19 | break; 20 | } 21 | } 22 | } 23 | } 24 | 25 | int main() 26 | { 27 | scanf("%d", &n); 28 | for (int i = 0; i < n; i++) 29 | { 30 | scanf("%d", &d[i]); 31 | } 32 | linear_basis(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Link-Cut-Tree(with-Reverse).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | #define N 10010 5 | 6 | using namespace std; 7 | 8 | int n, m; 9 | int ch[N][2], fa[N], tf[N]; 10 | bool rev[N]; 11 | 12 | inline void swap(int *x) 13 | { 14 | int temp = x[0]; 15 | x[0] = x[1]; 16 | x[1] = temp; 17 | } 18 | 19 | inline int which(int u) 20 | { 21 | return ch[fa[u]][0] == u ? 0 : 1; 22 | } 23 | 24 | void rotate(int u) 25 | { 26 | int p = fa[u]; 27 | int g = fa[p]; 28 | int k1 = which(u), k0 = which(p); 29 | int c = ch[u][k1 ^ 1]; 30 | fa[c] = p; 31 | fa[u] = g; 32 | fa[p] = u; 33 | ch[g][k0] = u; 34 | ch[p][k1] = c; 35 | ch[u][k1 ^ 1] = p; 36 | } 37 | 38 | void push_down(int u) 39 | { 40 | if (rev[u] == true) 41 | { 42 | swap(ch[u]); 43 | rev[u] = false; 44 | rev[ch[u][0]] ^= true, rev[ch[u][1]] ^= true; 45 | } 46 | } 47 | 48 | void splay(int u, int tar) 49 | { 50 | static int path[N]; 51 | int pc = 0; 52 | while (u != tar) 53 | { 54 | path[pc++] = u; 55 | u = fa[u]; 56 | } 57 | for (int i = pc - 1; i >= 0; i--) 58 | { 59 | push_down(path[i]); 60 | } 61 | u = path[0]; 62 | while (fa[u] != tar) 63 | { 64 | if (fa[fa[u]] != tar) 65 | { 66 | if (which(u) == which(fa[u])) rotate(fa[u]); 67 | else rotate(u); 68 | } 69 | rotate(u); 70 | } 71 | } 72 | 73 | int find_top(int u) 74 | { 75 | push_down(u); 76 | while (ch[u][0] != NIL) 77 | { 78 | u = ch[u][0]; 79 | push_down(u); 80 | } 81 | splay(u, NIL); 82 | return u; 83 | } 84 | 85 | int get_root(int u) 86 | { 87 | while (fa[u] != NIL) 88 | { 89 | u = fa[u]; 90 | } 91 | return u; 92 | } 93 | 94 | void access(int u) 95 | { 96 | int c = NIL; 97 | while (u != NIL) 98 | { 99 | splay(u, NIL); 100 | fa[ch[u][1]] = NIL; 101 | if (ch[u][1] != NIL) tf[find_top(ch[u][1])] = u; 102 | ch[u][1] = c; 103 | fa[c] = u; 104 | c = find_top(u); 105 | u = tf[c]; 106 | } 107 | } 108 | 109 | void change_root(int u) 110 | { 111 | access(u); 112 | splay(u, NIL); 113 | rev[u] = true; 114 | find_top(u); 115 | tf[u] = NIL; 116 | } 117 | 118 | void link(int u, int v) 119 | { 120 | change_root(v); 121 | tf[v] = u; 122 | } 123 | 124 | void cut(int u, int v) 125 | { 126 | change_root(u); 127 | access(v); 128 | splay(u, NIL); 129 | fa[v] = NIL; 130 | ch[u][1] = NIL; 131 | tf[v] = NIL; 132 | } 133 | 134 | bool query(int u, int v) 135 | { 136 | change_root(u); 137 | access(v); 138 | if (get_root(u) == get_root(v)) return true; 139 | else return false; 140 | } 141 | 142 | int main() 143 | { 144 | char op[10]; 145 | int u, v; 146 | scanf("%d%d", &n, &m); 147 | while (m--) 148 | { 149 | scanf("%s%d%d", op, &u, &v); 150 | if (op[0] == 'C') 151 | { 152 | link(u, v); 153 | } 154 | else if (op[0] == 'D') 155 | { 156 | cut(u, v); 157 | } 158 | else 159 | { 160 | printf("%s\n", query(u, v) == true ? "Yes" : "No"); 161 | } 162 | } 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /Link-Cut-Tree.cpp: -------------------------------------------------------------------------------- 1 | // Problem Name: [HNOI2010] 弹飞绵羊 Bounce 2 | 3 | #include 4 | 5 | #define NIL 0 6 | #define NODE_COUNT 200010 7 | 8 | using namespace std; 9 | 10 | class link_cut_tree 11 | { 12 | private: 13 | int ch[NODE_COUNT][2], fa[NODE_COUNT], size[NODE_COUNT], tf[NODE_COUNT]; 14 | 15 | public: 16 | link_cut_tree(); 17 | 18 | int get_size(int u); 19 | void set_tf(int u, int uf); 20 | 21 | int which(int u); 22 | void update(int u); 23 | void rotate(int u); 24 | void splay(int u, int tar); 25 | int find_top(int u); 26 | 27 | void access(int u); 28 | void link(int u, int v); 29 | void cut(int u); 30 | 31 | void print_fa(); 32 | }; 33 | 34 | int n, m; 35 | 36 | link_cut_tree::link_cut_tree() 37 | { 38 | for (int i = 1; i <= n + 1; i++) 39 | { 40 | size[i] = 1; 41 | } 42 | } 43 | 44 | int link_cut_tree::get_size(int u) 45 | { 46 | return size[u]; 47 | } 48 | 49 | void link_cut_tree::set_tf(int u, int uf) 50 | { 51 | tf[u] = uf; 52 | } 53 | 54 | int link_cut_tree::which(int u) 55 | { 56 | return ch[fa[u]][0] == u ? 0 : 1; 57 | } 58 | 59 | void link_cut_tree::update(int u) 60 | { 61 | size[u] = size[ch[u][0]] + size[ch[u][1]] + 1; 62 | } 63 | 64 | void link_cut_tree::rotate(int u) 65 | { 66 | int uk = which(u); 67 | int p = fa[u]; 68 | int q = fa[p]; 69 | int c = ch[u][uk ^ 1]; 70 | int pk = which(p); 71 | fa[c] = p; 72 | fa[u] = q; 73 | fa[p] = u; 74 | ch[p][uk] = c; 75 | ch[u][uk ^ 1] = p; 76 | ch[q][pk] = u; 77 | update(p); 78 | update(u); 79 | } 80 | 81 | void link_cut_tree::splay(int u, int tar) 82 | { 83 | while (fa[u] != tar) 84 | { 85 | if (fa[fa[u]] != tar) 86 | { 87 | if (which(u) == which(fa[u])) rotate(fa[u]); 88 | else rotate(u); 89 | } 90 | rotate(u); 91 | } 92 | } 93 | 94 | int link_cut_tree::find_top(int u) 95 | { 96 | int tar = fa[u]; 97 | while (ch[u][0] != NIL) 98 | { 99 | u = ch[u][0]; 100 | } 101 | splay(u, tar); 102 | return u; 103 | } 104 | 105 | void link_cut_tree::access(int u) 106 | { 107 | int top = NIL; 108 | do 109 | { 110 | splay(u, NIL); 111 | size[u] -= size[ch[u][1]]; 112 | fa[ch[u][1]] = NIL; 113 | ch[u][1] = top; 114 | fa[top] = u; 115 | update(u); 116 | top = find_top(u); 117 | u = tf[top]; 118 | } while (u != NIL); 119 | } 120 | 121 | void link_cut_tree::link(int u, int v) 122 | { 123 | tf[v] = u; 124 | } 125 | 126 | void link_cut_tree::cut(int u) 127 | { 128 | access(tf[u]); 129 | tf[u] = NIL; 130 | } 131 | 132 | void link_cut_tree::print_fa() 133 | { 134 | for (int i = 1; i <= n + 1; i++) 135 | { 136 | printf("fa[%d] = %d\n", i, fa[i]); 137 | } 138 | } 139 | 140 | int main() 141 | { 142 | int op, k, x; 143 | scanf("%d", &n); 144 | static link_cut_tree lct; 145 | for (int i = 1; i <= n; i++) 146 | { 147 | scanf("%d", &x); 148 | lct.set_tf(i, i + x > n ? n + 1 : i + x); 149 | } 150 | scanf("%d", &m); 151 | while (m--) 152 | { 153 | scanf("%d", &op); 154 | if (op == 1) 155 | { 156 | scanf("%d", &k); 157 | lct.access(k + 1); 158 | printf("%d\n", lct.get_size(n + 1) - 1); 159 | } 160 | else 161 | { 162 | scanf("%d%d", &k, &x); 163 | lct.cut(k + 1); 164 | lct.link(k + x > n ? n + 1 : k + 1 + x, k + 1); 165 | } 166 | } 167 | return 0; 168 | } 169 | -------------------------------------------------------------------------------- /Longest-Common-Substring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define STRING_LENGTH 300000 5 | 6 | using namespace std; 7 | 8 | struct sortinfo 9 | { 10 | int x, y, ord; 11 | }; 12 | 13 | int l; 14 | char s[STRING_LENGTH], t[STRING_LENGTH / 2]; 15 | int rank[STRING_LENGTH * 2], sa[STRING_LENGTH], height[STRING_LENGTH]; 16 | 17 | void radix_sort(sortinfo *d) 18 | { 19 | static sortinfo _d[STRING_LENGTH], res[STRING_LENGTH]; 20 | static int c[STRING_LENGTH]; 21 | memset(c, 0, sizeof(c)); 22 | for (int i = 0; i < l; i++) 23 | { 24 | c[d[i].y]++; 25 | } 26 | for (int i = 1; i <= l; i++) 27 | { 28 | c[i] += c[i - 1]; 29 | } 30 | for (int i = l - 1; i >= 0; i--) 31 | { 32 | _d[--c[d[i].y]] = d[i]; 33 | } 34 | memset(c, 0, sizeof(c)); 35 | for (int i = 0; i < l; i++) 36 | { 37 | c[_d[i].x]++; 38 | } 39 | for (int i = 1; i <= l; i++) 40 | { 41 | c[i] += c[i - 1]; 42 | } 43 | for (int i = l - 1; i >= 0; i--) 44 | { 45 | res[--c[_d[i].x]] = _d[i]; 46 | } 47 | for (int i = 0; i < l; i++) 48 | { 49 | d[i] = res[i]; 50 | } 51 | } 52 | 53 | void init_rank() 54 | { 55 | static int c[256]; 56 | static sortinfo d[STRING_LENGTH]; 57 | int x = 1; 58 | for (int i = 0; i < l; i++) 59 | { 60 | c[(int)s[i]] = 1; 61 | } 62 | for (int i = 0; i < 256; i++) 63 | { 64 | if (c[i] == 1) 65 | { 66 | c[i] = x++; 67 | } 68 | } 69 | for (int i = 0; i < l; i++) 70 | { 71 | rank[i] = c[(int)s[i]]; 72 | } 73 | for (int k = 1; k < l; k <<= 1) 74 | { 75 | for (int i = 0; i < l; i++) 76 | { 77 | d[i].x = rank[i]; 78 | d[i].y = rank[i + k]; 79 | d[i].ord = i; 80 | } 81 | radix_sort(d); 82 | x = 1; 83 | rank[d[0].ord] = 1; 84 | for (int i = 1; i < l; i++) 85 | { 86 | rank[d[i].ord] = (d[i].x == d[i - 1].x && d[i].y == d[i - 1].y ? x : ++x); 87 | } 88 | if (x == l) 89 | { 90 | break; 91 | } 92 | } 93 | } 94 | 95 | void rank_to_sa() 96 | { 97 | for (int i = 0; i < l; i++) 98 | { 99 | sa[rank[i]] = i; 100 | } 101 | } 102 | 103 | void init_height() 104 | { 105 | int k = 0; 106 | for (int i = 0; i < l; i++) 107 | { 108 | if (k > 0) 109 | { 110 | k--; 111 | } 112 | if (rank[i] == l) 113 | { 114 | continue; 115 | } 116 | for (; s[i + k] == s[sa[rank[i] + 1] + k]; k++) ; 117 | height[rank[i]] = k; 118 | } 119 | } 120 | 121 | int main() 122 | { 123 | int l1, l2; 124 | scanf("%s%s", s, t); 125 | l1 = strlen(s); 126 | l2 = strlen(t); 127 | s[l1] = '#'; 128 | strcat(s, t); 129 | l = l1 + l2; 130 | init_rank(); 131 | rank_to_sa(); 132 | init_height(); 133 | int maxlen = 0; 134 | for (int i = 1; i < l; i++) 135 | { 136 | if (height[i] > maxlen && ((sa[i] < l1 && sa[i + 1] > l1) || (sa[i] > l1 && sa[i + 1] < l1))) 137 | { 138 | maxlen = height[i]; 139 | } 140 | } 141 | printf("%d", maxlen); 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /Longest-Increasing-Subsequence(n·log(n)).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, d[1000010], least[1000010], longest; 6 | 7 | int binary_search(int x) 8 | { 9 | int l = 0, r = longest - 1; 10 | do 11 | { 12 | int mid = (l + r) >> 1; 13 | if (least[mid] >= x) 14 | { 15 | r = mid; 16 | } 17 | else 18 | { 19 | l = mid + 1; 20 | } 21 | } while (l < r); 22 | return l; 23 | } 24 | 25 | int main() 26 | { 27 | scanf("%d", &n); 28 | for (int i = 0; i < n; i++) 29 | { 30 | scanf("%d", &d[i]); 31 | } 32 | least[longest++] = d[0]; 33 | for (int i = 1; i < n; i++) 34 | { 35 | int l = binary_search(d[i]); 36 | if (d[i] > least[l]) 37 | { 38 | least[longest++] = d[i]; 39 | } 40 | else 41 | { 42 | least[l] = d[i]; 43 | } 44 | } 45 | printf("%d", longest); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Lowest-Common-Ancestor(Doubling).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct vertex 6 | { 7 | int first, depth; 8 | }V[100010]; 9 | 10 | struct edge 11 | { 12 | int endp, next; 13 | }E[200010]; 14 | 15 | int ec = 1, ivc; 16 | int fa[100010][25]; 17 | 18 | void add_edge(int u, int v) 19 | { 20 | E[ec].next = V[u].first; 21 | V[u].first = ec; 22 | E[ec].endp = v; 23 | ec++; 24 | } 25 | 26 | void DFS(int u, int prev, int depth) 27 | { 28 | if (fa[u][0] == 0) 29 | { 30 | fa[u][0] = prev; 31 | V[u].depth = depth; 32 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 33 | { 34 | DFS(E[cur].endp, u, depth + 1); 35 | } 36 | } 37 | } 38 | 39 | void init() 40 | { 41 | DFS(1, -1, 1); 42 | for (int i = 1; i <= 20; i++) 43 | { 44 | for (int j = 1; j <= ivc; j++) 45 | { 46 | fa[j][i] = fa[fa[j][i - 1]][i - 1]; 47 | } 48 | } 49 | } 50 | 51 | int lca(int a, int b) 52 | { 53 | if (V[b].depth > V[a].depth) 54 | { 55 | int temp = a; 56 | a = b; 57 | b = temp; 58 | } 59 | int delta = V[a].depth - V[b].depth, k = 0; 60 | while (delta > 0) 61 | { 62 | if ((delta & 1) == 1) 63 | { 64 | a = fa[a][k]; 65 | } 66 | k++; 67 | delta >>= 1; 68 | } 69 | if (a == b) 70 | { 71 | return a; 72 | } 73 | for (int i = 20; i >= 0; i--) 74 | { 75 | if (fa[a][i] != fa[b][i]) 76 | { 77 | a = fa[a][i]; 78 | b = fa[b][i]; 79 | } 80 | } 81 | return fa[a][0]; 82 | } 83 | 84 | int main() 85 | { 86 | int u, v; 87 | scanf("%d", &ivc); 88 | for (int i = 1; i < ivc; i++) 89 | { 90 | scanf("%d%d", &u, &v); 91 | add_edge(u, v); 92 | add_edge(v, u); 93 | } 94 | init(); 95 | while (true) 96 | { 97 | scanf("%d%d", &u, &v); 98 | printf("%d\n", lca(u, v)); 99 | } 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /Matrix-Multiplication(Naive).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int A[100][100], B[100][100], R[100][100]; 6 | 7 | // Matrix A is p columns and m rows. Matrix B is n columns and p rows. 8 | void matrix_multiplication(int p, int m, int n) 9 | { 10 | for (int i = 0; i < m; i++) 11 | { 12 | for (int j = 0; j < n; j++) 13 | { 14 | for (int k = 0; k < p; k++) 15 | { 16 | R[i][j] += A[i][k] * B[k][j]; 17 | } 18 | } 19 | } 20 | } 21 | 22 | int main() 23 | { 24 | int p, m, n; 25 | scanf("%d%d%d", &p, &m, &n); 26 | for (int i = 0; i < m; i++) 27 | { 28 | for (int j = 0; j < p; j++) 29 | { 30 | scanf("%d", &A[i][j]); 31 | } 32 | } 33 | for (int i = 0; i < p; i++) 34 | { 35 | for (int j = 0; j < n; j++) 36 | { 37 | scanf("%d", &B[i][j]); 38 | } 39 | } 40 | 41 | matrix_multiplication(p, m, n); 42 | 43 | for (int i = 0; i < m; i++) 44 | { 45 | for (int j = 0; j < n; j++) 46 | { 47 | printf("%d ", R[i][j]); 48 | } 49 | printf("\n"); 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Merge-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define INF 2000000000 5 | #define MAX_ELEMENT_COUNT 100000 6 | 7 | using namespace std; 8 | 9 | int d[MAX_ELEMENT_COUNT]; 10 | 11 | void merge(int l, int m, int r) 12 | { 13 | static int al[MAX_ELEMENT_COUNT], ar[MAX_ELEMENT_COUNT]; 14 | int il, ir; 15 | 16 | // Copy the data to the temporary array al & ar. 17 | for (il = l; il <= m; il++) 18 | { 19 | al[il] = d[il]; 20 | } 21 | al[m + 1] = INF; 22 | for (ir = m + 1; ir <= r; ir++) 23 | { 24 | ar[ir] = d[ir]; 25 | } 26 | ar[r + 1] = INF; 27 | 28 | // Merge al & ar into array d. 29 | il = l; 30 | ir = m + 1; 31 | for (int i = l; i <= r; i++) 32 | { 33 | if (al[il] < ar[ir]) 34 | { 35 | d[i] = al[il++]; 36 | } 37 | else 38 | { 39 | d[i] = ar[ir++]; 40 | } 41 | } 42 | } 43 | 44 | void merge_sort(int l, int r) 45 | { 46 | if (l < r) 47 | { 48 | int mid = (l + r) >> 1; 49 | merge_sort(l, mid); 50 | merge_sort(mid + 1, r); 51 | merge(l, mid, r); 52 | } 53 | } 54 | 55 | int main() 56 | { 57 | for (int i = 0; i < MAX_ELEMENT_COUNT; i++) 58 | { 59 | d[i] = rand(); 60 | } 61 | 62 | merge_sort(0, MAX_ELEMENT_COUNT - 1); 63 | 64 | for (int i = 0; i < MAX_ELEMENT_COUNT; i++) 65 | { 66 | printf("%d\n", d[i]); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Miller-Rabin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define LOWBIT(x) ((x) & (-(x))) 5 | 6 | #define COMPOSITE 0 7 | #define PRIME 1 8 | 9 | typedef long long ll; 10 | 11 | using namespace std; 12 | 13 | ll qpow(ll x, int y, int p) 14 | { 15 | if (y == 0) return 1; 16 | ll h = qpow(x * x % p, y >> 1, p); 17 | if ((y & 1) == 0) return h; 18 | else return h * x % p; 19 | } 20 | 21 | bool witness(int a, int n) 22 | { 23 | int t = LOWBIT(n - 1); 24 | int u = n / t; 25 | ll x = qpow(a, u, n); 26 | for (int i = 1; i < t; i <<= 1) 27 | { 28 | ll r = x * x % (ll)n; 29 | if (r == 1 && x != 1 && x != n - 1) return true; 30 | x = r; 31 | } 32 | if (x != 1) return true; 33 | return false; 34 | } 35 | 36 | bool Miller_Rabin(int n, int s) 37 | { 38 | if (n == 2) return PRIME; 39 | if ((n & 1) == 0) return COMPOSITE; 40 | while (s--) 41 | { 42 | if (witness(rand() % (n - 2) + 2, n) == true) return COMPOSITE; 43 | } 44 | return PRIME; 45 | } 46 | 47 | int main() 48 | { 49 | int n; 50 | while (true) 51 | { 52 | scanf("%d", &n); 53 | printf("%s\n", Miller_Rabin(n, 10) == COMPOSITE ? "COMPOSITE" : "PRIME"); 54 | } 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /Min-Heap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_HEAP_SIZE 100000 5 | 6 | using namespace std; 7 | 8 | int n, H[MAX_HEAP_SIZE], heapsize; 9 | 10 | void min_heapify(int i) 11 | { 12 | int smallest = i; 13 | int lch = i << 1; 14 | int rch = lch + 1; 15 | 16 | if (lch <= heapsize && H[smallest] > H[lch]) 17 | { 18 | smallest = lch; 19 | } 20 | if (rch <= heapsize && H[smallest] > H[rch]) 21 | { 22 | smallest = rch; 23 | } 24 | 25 | if (smallest != i) 26 | { 27 | int temp = H[smallest]; 28 | H[smallest] = H[i]; 29 | H[i] = temp; 30 | min_heapify(smallest); 31 | } 32 | } 33 | 34 | void build_heap() 35 | { 36 | for (int i = heapsize >> 1; i >= 1; i--) 37 | { 38 | min_heapify(i); 39 | } 40 | } 41 | 42 | void insert(int x) 43 | { 44 | H[++heapsize] = x; 45 | 46 | int ch = heapsize, p = heapsize >> 1; 47 | while (H[p] > H[ch] && p >= 1) 48 | { 49 | int temp = H[p]; 50 | H[p] = H[ch]; 51 | H[ch] = temp; 52 | 53 | ch = p; 54 | p >>= 1; 55 | } 56 | } 57 | 58 | int main() 59 | { 60 | scanf("%d", &n); 61 | for (int i = 0; i < n; i++) 62 | { 63 | int x; 64 | scanf("%d", &x); 65 | insert(x); 66 | } 67 | // Add more actions here. 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Modular-Multiplicative-Inverse-Sieve(Factorial,Linear).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_N 10000000 4 | 5 | typedef long long ll; 6 | 7 | using namespace std; 8 | 9 | // p must be a prime greater than n. 10 | ll n, fac_inv[MAX_N], p; 11 | 12 | ll qpow(ll x, ll y) 13 | { 14 | if (y == 1) return x; 15 | ll t = qpow(x, y >> 1); 16 | t = t * t % p; 17 | if ((y & 1) == 0) return t; 18 | else return t * x % p; 19 | } 20 | 21 | ll fac(ll x) 22 | { 23 | ll res = 1; 24 | for (int i = 2; i <= x; i++) 25 | { 26 | res = res * i % p; 27 | } 28 | return res; 29 | } 30 | 31 | void fac_inv_sieve() 32 | { 33 | fac_inv[n] = qpow(fac(n), p - 2); 34 | for (ll i = n - 1; i >= 1; i--) 35 | { 36 | fac_inv[i] = fac_inv[i + 1] * (i + 1) % p; 37 | } 38 | } 39 | 40 | int main() 41 | { 42 | scanf("%lld%lld", &n, &p); 43 | fac_inv_sieve(); 44 | for (int i = 1; i <= n; i++) 45 | { 46 | printf("inv(fac(%d)) mod %lld = %lld\n", i, p, fac_inv[i]); 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Modular-Multiplicative-Inverse-Sieve(Linear).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MOD 1000000007 4 | #define MAX_ELEMENT 10000000 5 | 6 | int rev[MAX_ELEMENT]; 7 | 8 | void sieve(int n) 9 | { 10 | rev[1] = 1; 11 | for (int i = 2; i <= n; i++) 12 | { 13 | rev[i] = (int)(-(long long)(MOD / i) * (long long)rev[MOD % i] % (long long)MOD); 14 | rev[i] = (rev[i] % MOD + MOD) % MOD; 15 | } 16 | } 17 | 18 | int main() 19 | { 20 | int n; 21 | scanf("%d", &n); 22 | sieve(n); 23 | for (int i = 1; i <= n; i++) 24 | { 25 | printf("rev(%d) = %d\n", i, rev[i]); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Modular-Multiplicative-Inverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int extended_gcd(int a, int b, int &x, int &y) 6 | { 7 | if (b == 0) 8 | { 9 | x = 1; 10 | y = 0; 11 | return a; 12 | } 13 | int _gcd = extended_gcd(b, a % b, x, y); 14 | int temp = x; 15 | x = y; 16 | y = temp - (a / b) * y; 17 | return _gcd; 18 | } 19 | 20 | int inverse(int a, int p) 21 | { 22 | int x, y; 23 | extended_gcd(a, p, x, y); 24 | return (x % p + p) % p; 25 | } 26 | 27 | int main() 28 | { 29 | int a, p; 30 | 31 | while (true) 32 | { 33 | scanf("%d%d", &a, &p); 34 | printf("%d\n", inverse(a, p)); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Non-Rotating-Treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | node *lch, *rch; 11 | int key, pr; 12 | node(int _key); 13 | }*root, *nil; 14 | 15 | node::node(int _key = 0) : lch(nil), rch(nil), key(_key), pr(rand()) { } 16 | 17 | void init() 18 | { 19 | nil = new node; 20 | root = nil; 21 | } 22 | 23 | pair split(node *u, int x) 24 | { 25 | if (u == nil) 26 | { 27 | return make_pair(nil, nil); 28 | } 29 | if (x <= u->key) 30 | { 31 | pair res = split(u->lch, x); 32 | u->lch = res.second; 33 | return make_pair(res.first, u); 34 | } 35 | else 36 | { 37 | pair res = split(u->rch, x); 38 | u->rch = res.first; 39 | return make_pair(u, res.second); 40 | } 41 | } 42 | 43 | node* merge(node *u, node *v) 44 | { 45 | if (u == nil) 46 | { 47 | return v; 48 | } 49 | else if (v == nil) 50 | { 51 | return u; 52 | } 53 | if (u->pr > v->pr) 54 | { 55 | u->rch = merge(u->rch, v); 56 | return u; 57 | } 58 | else 59 | { 60 | v->lch = merge(u, v->lch); 61 | return v; 62 | } 63 | } 64 | 65 | int find(node *u, int x) 66 | { 67 | if (u == nil) 68 | { 69 | return 0; 70 | } 71 | if (u->key == x) 72 | { 73 | return 1; 74 | } 75 | if (x < u->key) 76 | { 77 | return find(u->lch, x); 78 | } 79 | else 80 | { 81 | return find(u->rch, x); 82 | } 83 | } 84 | 85 | int find(int x) 86 | { 87 | return find(root, x); 88 | } 89 | 90 | void insert(int x) 91 | { 92 | if (find(root, x) == 1) 93 | { 94 | return; 95 | } 96 | node *u = new node(x); 97 | pair rts = split(root, x); 98 | rts.first = merge(rts.first, u); 99 | root = merge(rts.first, rts.second); 100 | } 101 | 102 | void print_tree(node *u) 103 | { 104 | if (u != nil) 105 | { 106 | printf("("); 107 | print_tree(u->lch); 108 | printf("%d", u->key); 109 | print_tree(u->rch); 110 | printf(")"); 111 | } 112 | } 113 | 114 | int main() 115 | { 116 | char op[10]; 117 | int x; 118 | init(); 119 | while (true) 120 | { 121 | scanf("%s", op); 122 | if (strcmp(op, "insert") == 0) 123 | { 124 | scanf("%d", &x); 125 | insert(x); 126 | } 127 | else if (strcmp(op, "find") == 0) 128 | { 129 | scanf("%d", &x); 130 | printf("%d\n", find(x)); 131 | } 132 | else if (strcmp(op, "exit") == 0) 133 | { 134 | break; 135 | } 136 | else 137 | { 138 | printf("Command not found.\n"); 139 | } 140 | } 141 | return 0; 142 | } 143 | -------------------------------------------------------------------------------- /Palindromic-Tree.cpp: -------------------------------------------------------------------------------- 1 | // Problem Name: Palindromes 2 | // Source: [APIO2014] 3 | 4 | #include 5 | #include 6 | 7 | #define NIL 0 8 | #define ALPHABET_SIZE 26 9 | #define STRING_LENGTH 100000 10 | 11 | using namespace std; 12 | 13 | struct node 14 | { 15 | node *next[ALPHABET_SIZE], *fail; 16 | int start, len; 17 | node (int _start = 0, int _len = 0) : fail(NIL), start(_start), len(_len) { memset(next, 0, sizeof(next)); } 18 | }*root, *empty, *last; 19 | 20 | char str[STRING_LENGTH]; 21 | int len; 22 | 23 | void extend(char x, int pos) 24 | { 25 | node *u = last; 26 | while (str[pos] != str[pos - u->len - 1]) u = u->fail; 27 | if (u->next[x] == NIL) 28 | { 29 | node *cur = new node(pos - u->len - 1, u->len + 2); 30 | u->next[x] = cur; 31 | u = u->fail; 32 | if (u == NIL) cur->fail = empty; 33 | else 34 | { 35 | while (str[pos] != str[pos - u->len - 1]) u = u->fail; 36 | cur->fail = u->next[x]; 37 | } 38 | last = cur; 39 | } 40 | else last = u->next[x]; 41 | } 42 | 43 | void build() 44 | { 45 | str[0] = '\xFF'; 46 | root = new node(0, -1); 47 | empty = new node(0, 0); 48 | empty->fail = root; 49 | last = empty; 50 | for (int i = 1; i <= len; i++) 51 | { 52 | extend(str[i] - 'a', i); 53 | } 54 | } 55 | 56 | void print_substring(int l, int r) 57 | { 58 | printf("\t"); 59 | for (int i = l; i <= r; i++) 60 | { 61 | printf("%c", str[i]); 62 | } 63 | printf("\n"); 64 | } 65 | 66 | void dfs(node *u) 67 | { 68 | if (u->len > 0) print_substring(u->start, u->start + u->len - 1); 69 | for (int i = 0; i < ALPHABET_SIZE; i++) 70 | { 71 | if (u->next[i] != NIL) dfs(u->next[i]); 72 | } 73 | } 74 | 75 | int main() 76 | { 77 | scanf("%s", str + 1); 78 | len = strlen(str + 1); 79 | build(); 80 | printf("odd:\n"); 81 | dfs(root); 82 | printf("even:\n"); 83 | dfs(empty); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /Permutation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, s[10], sp = 0; 6 | bool ins[11]; 7 | 8 | void DFS() 9 | { 10 | if (sp == n) 11 | { 12 | for (int i = 0; i < sp; i++) 13 | { 14 | printf("%d ", s[i]); 15 | } 16 | printf("\n"); 17 | return; 18 | } 19 | for (int i = 1; i <= n; i++) 20 | { 21 | if (ins[i] == false) 22 | { 23 | ins[i] = true; 24 | s[sp++] = i; 25 | DFS(); 26 | ins[i] = false; 27 | sp--; 28 | } 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | scanf("%d", &n); 35 | DFS(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Persistent-Array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | #define ELEMENT_COUNT 100000 5 | #define EDITION_COUNT 100000 6 | #define POOL_SIZE 1000000 7 | 8 | using namespace std; 9 | 10 | struct node 11 | { 12 | node *lch, *rch; 13 | int v; 14 | node(int _v = 0) : v(_v) { lch = rch = NIL; } 15 | void* operator new (size_t); 16 | }*root[EDITION_COUNT], pool[POOL_SIZE]; 17 | int top = 0; 18 | 19 | int n, d[ELEMENT_COUNT], cur = 0, used = 1; 20 | 21 | void* node::operator new (size_t) 22 | { 23 | return pool + top++; 24 | } 25 | 26 | void build(node *&u, int l, int r) 27 | { 28 | u = new node; 29 | if (l == r) 30 | { 31 | u->v = d[l]; 32 | } 33 | else 34 | { 35 | int mid = (l + r) >> 1; 36 | build(u->lch, l, mid); 37 | build(u->rch, mid + 1, r); 38 | } 39 | } 40 | 41 | void modify(node *&u, node *old, int l, int r, int k, int v) 42 | { 43 | u = new node; 44 | if (l == r) 45 | { 46 | u->v = v; 47 | } 48 | else 49 | { 50 | int mid = (l + r) >> 1; 51 | if (k <= mid) 52 | { 53 | u->rch = old->rch; 54 | modify(u->lch, old->lch, l, mid, k, v); 55 | } 56 | else 57 | { 58 | u->lch = old->lch; 59 | modify(u->rch, old->rch, mid + 1, r, k, v); 60 | } 61 | } 62 | } 63 | 64 | int query(node *u, int l, int r, int k) 65 | { 66 | if (l == r) 67 | { 68 | return u->v; 69 | } 70 | else 71 | { 72 | int mid = (l + r) >> 1; 73 | if (k <= mid) 74 | { 75 | return query(u->lch, l, mid, k); 76 | } 77 | else 78 | { 79 | return query(u->rch, mid + 1, r, k); 80 | } 81 | } 82 | } 83 | 84 | int main() 85 | { 86 | int op, e, k, x; 87 | scanf("%d", &n); 88 | for (int i = 1; i <= n; i++) 89 | { 90 | scanf("%d", &d[i]); 91 | } 92 | build(root[cur], 1, n); 93 | while (true) 94 | { 95 | scanf("%d", &op); 96 | if (op == 1) 97 | { 98 | scanf("%d%d", &k, &x); 99 | modify(root[used], root[cur], 1, n, k, x); 100 | cur = used; 101 | used++; 102 | } 103 | else if (op == 2) 104 | { 105 | scanf("%d%d", &e, &k); 106 | printf("%d\n", query(root[e], 1, n, k)); 107 | } 108 | else if (op == 3) 109 | { 110 | scanf("%d", &e); 111 | cur = e; 112 | } 113 | else if (op == 0) 114 | { 115 | break; 116 | } 117 | else 118 | { 119 | printf("No such command!\n"); 120 | } 121 | } 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /Persistent-Segment-Tree(Sum).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ELEMENT_COUNT 100000 4 | #define EDITION_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | int l, r, sum; 11 | node *lch, *rch; 12 | }*root[EDITION_COUNT]; 13 | 14 | int n, d[ELEMENT_COUNT], hs = 0; 15 | 16 | void build(int l, int r, node *u) 17 | { 18 | u->l = l; 19 | u->r = r; 20 | if (l == r) 21 | { 22 | u->sum = d[l]; 23 | } 24 | else 25 | { 26 | int mid = (l + r) >> 1; 27 | build(l, mid, u->lch = new node); 28 | build(mid + 1, r, u->rch = new node); 29 | u->sum = u->lch->sum + u->rch->sum; 30 | } 31 | } 32 | 33 | int query(int l, int r, node *u) 34 | { 35 | if (u->l == l && u->r == r) 36 | { 37 | return u->sum; 38 | } 39 | else 40 | { 41 | int mid = (u->l + u->r) >> 1; 42 | if (r <= mid) 43 | { 44 | return query(l, r, u->lch); 45 | } 46 | else if (l > mid) 47 | { 48 | return query(l, r, u->rch); 49 | } 50 | else 51 | { 52 | return query(l, mid, u->lch) + query(mid + 1, r, u->rch); 53 | } 54 | } 55 | } 56 | 57 | void modify(int k, int v, node *u, node *ori) 58 | { 59 | u->l = ori->l; 60 | u->r = ori->r; 61 | if (u->l == u->r) 62 | { 63 | u->sum = v; 64 | } 65 | else 66 | { 67 | int mid = (u->l + u->r) >> 1; 68 | if (k <= mid) 69 | { 70 | u->rch = ori->rch; 71 | u->lch = new node; 72 | modify(k, v, u->lch, ori->lch); 73 | } 74 | else 75 | { 76 | u->lch = ori->lch; 77 | u->rch = new node; 78 | modify(k, v, u->rch, ori->rch); 79 | } 80 | u->sum = u->lch->sum + u->rch->sum; 81 | } 82 | } 83 | 84 | int main() 85 | { 86 | scanf("%d", &n); 87 | for (int i = 1; i <= n; i++) 88 | { 89 | scanf("%d", &d[i]); 90 | } 91 | build(1, n, root[0] = new node); 92 | int in, edition, ql, qr, k, v; 93 | while (true) 94 | { 95 | scanf("%d", &in); 96 | if (in == 1) 97 | { 98 | scanf("%d%d%d", &edition, &ql, &qr); 99 | printf("%d\n", query(ql, qr, root[edition])); 100 | } 101 | else if (in == 2) 102 | { 103 | scanf("%d%d", &k, &v); 104 | hs++; 105 | modify(k, v, root[hs] = new node, root[hs - 1]); 106 | } 107 | else if (in == 3) 108 | { 109 | printf("Current edition : %d\n", hs); 110 | } 111 | else if (in == 0) 112 | { 113 | return 0; 114 | } 115 | else 116 | { 117 | printf("No such command!\n"); 118 | } 119 | } 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /Persistent-Treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NIL 0 5 | #define EDITION_COUNT 100000 6 | 7 | using namespace std; 8 | 9 | struct node 10 | { 11 | node *ch[2]; 12 | int key, pr; 13 | node(int _key = 0, int _pr = 0) : key(_key), pr(_pr) { } 14 | }*root[EDITION_COUNT]; 15 | 16 | int hs = 0; 17 | 18 | void rotate(node *&u, int dir) 19 | { 20 | node *o = u->ch[dir]; 21 | u->ch[dir] = o->ch[dir ^ 1]; 22 | o->ch[dir ^ 1] = u; 23 | u = o; 24 | } 25 | 26 | int cmp(int ikey, int ukey) 27 | { 28 | if (ikey == ukey) 29 | return -1; 30 | return ikey < ukey ? 0 : 1; 31 | } 32 | 33 | void insert(node *&u, node *prev, int key, int pr) 34 | { 35 | if (prev == NIL) 36 | { 37 | u = new node(key, pr); 38 | return; 39 | } 40 | u = new node(prev->key, prev->pr); 41 | int k = cmp(key, prev->key); 42 | u->ch[k ^ 1] = prev->ch[k ^ 1]; 43 | if (k == -1) 44 | { 45 | u->ch[k] = prev->ch[k]; 46 | return; 47 | } 48 | insert(u->ch[k], prev->ch[k], key, pr); 49 | if (u->ch[k]->pr > u->pr) 50 | { 51 | rotate(u, k); 52 | } 53 | } 54 | 55 | int find(node *&u, int key) 56 | { 57 | if (u == NIL) 58 | { 59 | return -1; 60 | } 61 | else 62 | { 63 | int k = cmp(key, u->key); 64 | if (k == -1) 65 | { 66 | return 1; 67 | } 68 | return find(u->ch[k], key); 69 | } 70 | } 71 | 72 | int main() 73 | { 74 | int in, edition, key; 75 | while (true) 76 | { 77 | scanf("%d", &in); 78 | if (in == 1) 79 | { 80 | scanf("%d", &key); 81 | insert(root[hs + 1], root[hs], key, rand()); 82 | hs++; 83 | } 84 | else if (in == 2) 85 | { 86 | scanf("%d%d", &edition, &key); 87 | printf("%d\n", find(root[edition], key)); 88 | } 89 | else if (in == 3) 90 | { 91 | printf("Current edition : %d\n", hs); 92 | } 93 | else if (in == 0) 94 | { 95 | return 0; 96 | } 97 | else 98 | { 99 | printf("No such command!\n"); 100 | } 101 | } 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /Persistent-Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define NIL 0 6 | 7 | using namespace std; 8 | 9 | struct node 10 | { 11 | node *next[26]; 12 | int cnt; 13 | node() : cnt(0) { memset(next, 0, sizeof(next)); } 14 | }; 15 | 16 | struct vertex 17 | { 18 | int first, depth; 19 | node *root; 20 | }V[100010]; 21 | 22 | struct edge 23 | { 24 | int endp, next; 25 | }E[200010]; 26 | 27 | int n, ec = 2, q, fa[100010][18], k; 28 | char str[100010][12]; 29 | 30 | inline void add_edge(int u, int v) 31 | { 32 | E[ec].next = V[u].first; 33 | V[u].first = ec; 34 | E[ec].endp = v; 35 | ec++; 36 | } 37 | 38 | void insert(node *&u, node *old, char *s, int len, int p) 39 | { 40 | u = new node; 41 | if (old != NIL) *u = *old; 42 | u->cnt++; 43 | if (p == len) return; 44 | int x = s[p] - 'a'; 45 | u->next[x] = NIL; 46 | insert(u->next[x], old == NIL ? NIL : old->next[x], s, len, p + 1); 47 | } 48 | 49 | int query(node *u, char *s, int len, int p) 50 | { 51 | if (u == NIL) return 0; 52 | if (p == len) return u->cnt; 53 | int x = s[p] - 'a'; 54 | return query(u->next[x], s, len, p + 1); 55 | } 56 | 57 | int query(int u, char *s) 58 | { 59 | return query(V[u].root, s, strlen(s), 0); 60 | } 61 | 62 | void dfs(int u, int fa, int depth) 63 | { 64 | ::fa[u][0] = fa; 65 | V[u].depth = depth; 66 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 67 | { 68 | if (E[cur].endp != fa) 69 | { 70 | insert(V[E[cur].endp].root, V[u].root, str[cur >> 1], strlen(str[cur >> 1]), 0); 71 | dfs(E[cur].endp, u, depth + 1); 72 | } 73 | } 74 | } 75 | 76 | void init() 77 | { 78 | V[1].root = new node; 79 | dfs(1, 0, 0); 80 | for (k = 1; (1 << k) <= n; k++) 81 | { 82 | for (int i = 1; i <= n; i++) 83 | { 84 | fa[i][k] = fa[fa[i][k - 1]][k - 1]; 85 | } 86 | } 87 | k--; 88 | } 89 | 90 | int lca(int x, int y) 91 | { 92 | if (V[x].depth < V[y].depth) 93 | { 94 | swap(x, y); 95 | } 96 | for (int i = k; i >= 0; i--) 97 | { 98 | if (V[x].depth - (1 << i) >= V[y].depth) 99 | { 100 | x = fa[x][i]; 101 | } 102 | } 103 | if (x == y) 104 | { 105 | return x; 106 | } 107 | for (int i = k; i >= 0; i--) 108 | { 109 | if (fa[x][i] != fa[y][i]) 110 | { 111 | x = fa[x][i]; 112 | y = fa[y][i]; 113 | } 114 | } 115 | return fa[x][0]; 116 | } 117 | 118 | int main() 119 | { 120 | scanf("%d", &n); 121 | int u, v; 122 | for (int i = 1; i < n; i++) 123 | { 124 | scanf("%d%d%s", &u, &v, str[i]); 125 | add_edge(u, v); 126 | add_edge(v, u); 127 | } 128 | init(); 129 | scanf("%d", &q); 130 | char s[12]; 131 | while (q--) 132 | { 133 | scanf("%d%d%s", &u, &v, s); 134 | printf("%d\n", query(u, s) + query(v, s) - query(lca(u, v), s) * 2); 135 | } 136 | return 0; 137 | } 138 | -------------------------------------------------------------------------------- /Prim.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long ll; 5 | 6 | using namespace std; 7 | 8 | struct vertex 9 | { 10 | int first; 11 | }V[5010]; 12 | 13 | struct edge 14 | { 15 | int endp, next, w; 16 | }E[400010]; 17 | 18 | struct queue_node 19 | { 20 | int u; 21 | ll dis; 22 | queue_node(int _u = 0, ll _dis = 0) : u(_u), dis(_dis) { } 23 | }; 24 | 25 | int n, m, ec = 2; 26 | bool vis[5010]; 27 | 28 | inline void add_edge(int u, int v, int w) 29 | { 30 | E[ec].next = V[u].first; 31 | V[u].first = ec; 32 | E[ec].endp = v; 33 | E[ec].w = w; 34 | ec++; 35 | } 36 | 37 | inline bool operator < (const queue_node &x, const queue_node &y) 38 | { 39 | return x.dis > y.dis; 40 | } 41 | 42 | ll prim() 43 | { 44 | ll res = 0; 45 | int vc = 0; 46 | priority_queue Q; 47 | Q.push(queue_node(1, 0)); 48 | while (vc < n) 49 | { 50 | queue_node u = Q.top(); 51 | Q.pop(); 52 | if (vis[u.u] == false) 53 | { 54 | res += u.dis; 55 | vis[u.u] = true; 56 | vc++; 57 | for (int cur = V[u.u].first; cur != 0; cur = E[cur].next) 58 | { 59 | Q.push(queue_node(E[cur].endp, E[cur].w)); 60 | } 61 | } 62 | } 63 | return res; 64 | } 65 | 66 | int main() 67 | { 68 | scanf("%d%d", &n, &m); 69 | int u, v, w; 70 | for (int i = 0; i < m; i++) 71 | { 72 | scanf("%d%d%d", &u, &v, &w); 73 | add_edge(u, v, w); 74 | add_edge(v, u, w); 75 | } 76 | printf("%lld\n", prim()); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Prime-Check(Naive).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | bool check(int x) 6 | { 7 | for (int i = 2; i * i <= x; i++) 8 | { 9 | if (x % i == 0) 10 | { 11 | return false; 12 | } 13 | } 14 | return true; 15 | } 16 | 17 | int main() 18 | { 19 | int n; 20 | while (scanf("%d", &n) > 0) 21 | { 22 | printf("%s\n", check(n) == true ? "YES" : "NO"); 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Prime-Sieve(Linear).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_ELEMENT 1000000 4 | 5 | using namespace std; 6 | 7 | int prime[MAX_ELEMENT], pc, div[MAX_ELEMENT]; 8 | 9 | void sieve(int n) 10 | { 11 | for (int i = 2; i <= n; i++) 12 | { 13 | if (div[i] == 0) 14 | { 15 | prime[pc++] = i; 16 | div[i] = i; 17 | } 18 | for (int j = 0; j < pc; j++) 19 | { 20 | if (i * prime[j] > n) break; 21 | div[i * prime[j]] = prime[j]; 22 | if (div[i] == prime[j]) break; 23 | } 24 | } 25 | } 26 | 27 | int main() 28 | { 29 | int n; 30 | scanf("%d", &n); 31 | sieve(n); 32 | for (int i = 0; i < pc; i++) 33 | { 34 | printf("%d ", prime[i]); 35 | } 36 | printf("\n"); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Primitive-Root.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef long long ll; 4 | 5 | using namespace std; 6 | 7 | ll p; 8 | 9 | ll qpow(ll x, ll y) 10 | { 11 | if (y == 1) return x; 12 | ll t = qpow(x, y >> 1); 13 | t = t * t % p; 14 | if ((y & 1) == 0) return t; 15 | return t * x % p; 16 | } 17 | 18 | int main() 19 | { 20 | ll x; 21 | while (true) 22 | { 23 | scanf("%lld", &p); 24 | for (ll k = 2; ; k++) 25 | { 26 | x = p - 1; 27 | for (ll i = 2; i * i <= x; i++) 28 | { 29 | if (x % i == 0) 30 | { 31 | if (qpow(k, (p - 1) / i) == 1) goto NEXT; 32 | while (x % i == 0) x /= i; 33 | } 34 | } 35 | if (x != 1) 36 | { 37 | if (qpow(k, (p - 1) / x) == 1) goto NEXT; 38 | } 39 | printf("%lld\n", k); 40 | break; 41 | NEXT:; 42 | } 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /Prüfer-Sequence(Tree-to-Sequence).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define VERTEX_COUNT 100010 5 | #define EDGE_COUNT 200010 6 | 7 | using namespace std; 8 | 9 | struct vertex 10 | { 11 | int first, subcnt, fa; 12 | bool vis; 13 | }V[VERTEX_COUNT]; 14 | 15 | struct edge 16 | { 17 | int endp, next; 18 | }E[EDGE_COUNT]; 19 | 20 | int ivc, ec = 2, prufer[VERTEX_COUNT], pc; 21 | priority_queue< int, vector, greater > Q; 22 | 23 | inline void add_edge(int u, int v) 24 | { 25 | E[ec].next = V[u].first; 26 | V[u].first = ec; 27 | E[ec].endp = v; 28 | ec++; 29 | } 30 | 31 | void dfs(int u, int fa) 32 | { 33 | V[u].vis = true; 34 | V[u].fa = fa; 35 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 36 | { 37 | if (V[E[cur].endp].vis == false) dfs(E[cur].endp, u), V[u].subcnt++; 38 | } 39 | } 40 | 41 | int main() 42 | { 43 | int u, v; 44 | scanf("%d", &ivc); 45 | for (int i = 1; i < ivc; i++) 46 | { 47 | scanf("%d%d", &u, &v); 48 | add_edge(u, v); 49 | add_edge(v, u); 50 | } 51 | dfs(1, 0); 52 | for (int i = 1; i <= ivc; i++) 53 | { 54 | if (E[V[i].first].next == 0) Q.push(i); 55 | } 56 | for (int i = 3; i <= ivc; i++) 57 | { 58 | int u = Q.top();printf("pop : %d, fa = %d\n", u, V[u].fa); 59 | Q.pop(); 60 | if (V[u].fa == 0) 61 | { 62 | for (int cur = V[u].first; cur != 0; cur = E[cur].next) 63 | { 64 | if (V[E[cur].endp].fa != 0) 65 | { 66 | prufer[pc++] = E[cur].endp; 67 | V[E[cur].endp].fa = 0; 68 | if (V[E[cur].endp].subcnt == 1) Q.push(E[cur].endp); 69 | break; 70 | } 71 | } 72 | } 73 | else 74 | { 75 | prufer[pc++] = V[u].fa; 76 | V[V[u].fa].subcnt--; 77 | if (V[V[u].fa].subcnt == 0) Q.push(V[u].fa); 78 | else if (V[V[u].fa].subcnt == 1 && V[V[u].fa].fa == 0) Q.push(V[u].fa); 79 | } 80 | } 81 | for (int i = 0; i < pc; i++) 82 | { 83 | printf("%d ", prufer[i]); 84 | } 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define QUEUE_SIZE 100000 4 | 5 | using namespace std; 6 | 7 | int Q[QUEUE_SIZE], hp = 0, tp = 0, M[QUEUE_SIZE], mhp = 0, mtp = 0; 8 | 9 | void enqueue(int x) 10 | { 11 | Q[tp++] = x; 12 | tp %= QUEUE_SIZE; 13 | 14 | while (mhp != mtp && x > M[mhp]) 15 | { 16 | mtp = (mtp + 1) % QUEUE_SIZE; 17 | } 18 | M[mtp++] = x; 19 | mtp %= QUEUE_SIZE; 20 | } 21 | 22 | int dequeue() 23 | { 24 | int ret = Q[hp++]; 25 | hp %= QUEUE_SIZE; 26 | 27 | if (ret == M[mhp]) 28 | { 29 | mhp = (mhp + 1) % QUEUE_SIZE; 30 | } 31 | 32 | return ret; 33 | } 34 | 35 | bool empty() 36 | { 37 | return hp == tp; 38 | } 39 | 40 | int get_max() 41 | { 42 | return M[mhp]; 43 | } 44 | 45 | int main() 46 | { 47 | while (true) 48 | { 49 | // 1 : enqueue; 2 : dequeue; 3 : get_max. 50 | int o, x; 51 | scanf("%d", &o); 52 | 53 | switch (o) 54 | { 55 | case 1: 56 | scanf("%d", &x); 57 | enqueue(x); 58 | break; 59 | case 2: 60 | x = dequeue(); 61 | printf("%d\n", x); 62 | break; 63 | case 3: 64 | printf("%d\n", get_max()); 65 | break; 66 | } 67 | } 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Quick-Sort(Extra-Optimised).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define ELEMENT_COUNT 1000000 6 | 7 | using namespace std; 8 | 9 | int d[ELEMENT_COUNT]; 10 | 11 | int flag = 0; 12 | 13 | void qsort(int l, int r) 14 | { 15 | if (l < r) 16 | { 17 | int _rand = rand() % (r - l + 1) + l; 18 | 19 | int temp = d[_rand]; 20 | d[_rand] = d[r]; 21 | d[r] = temp; 22 | 23 | int x = d[r]; 24 | int j = l - 1; 25 | 26 | for (int i = l; i < r; i++) 27 | { 28 | if (d[i] < x) 29 | { 30 | j++; 31 | temp = d[i]; 32 | d[i] = d[j]; 33 | d[j] = temp; 34 | } 35 | else if (d[i] == x) 36 | { 37 | if ((flag++ & 1) == 0) 38 | { 39 | j++; 40 | temp = d[i]; 41 | d[i] = d[j]; 42 | d[j] = temp; 43 | } 44 | } 45 | } 46 | j++; 47 | temp = d[r]; 48 | d[r] = d[j]; 49 | d[j] = temp; 50 | 51 | qsort(l, j - 1); 52 | qsort(j + 1, r); 53 | } 54 | } 55 | 56 | int main() 57 | { 58 | int n; 59 | scanf("%d", &n); 60 | 61 | for (int i = 0; i < n; i++) 62 | { 63 | scanf("%d", &d[i]); 64 | } 65 | 66 | qsort(0, n - 1); 67 | 68 | for (int i = 0; i < n; i++) 69 | { 70 | printf("%d ", d[i]); 71 | } 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /Quick-Sort(Randomized).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define ELEMENT_COUNT 1000000 5 | 6 | using namespace std; 7 | 8 | int d[ELEMENT_COUNT]; 9 | 10 | int flag = 0; 11 | 12 | void qsort(int l, int r) 13 | { 14 | if (l < r) 15 | { 16 | int _rand = rand() % (r - l + 1) + l; 17 | 18 | int temp = d[_rand]; 19 | d[_rand] = d[r]; 20 | d[r] = temp; 21 | 22 | int x = d[r]; 23 | int j = l - 1; 24 | 25 | for (int i = l; i <= r; i++) 26 | { 27 | if (d[i] <= x) 28 | { 29 | j++; 30 | temp = d[i]; 31 | d[i] = d[j]; 32 | d[j] = temp; 33 | } 34 | } 35 | 36 | qsort(l, j - 1); 37 | qsort(j + 1, r); 38 | } 39 | } 40 | 41 | int main() 42 | { 43 | int n; 44 | scanf("%d", &n); 45 | 46 | for (int i = 0; i < n; i++) 47 | { 48 | scanf("%d", &d[i]); 49 | } 50 | 51 | qsort(0, n - 1); 52 | 53 | for (int i = 0; i < n; i++) 54 | { 55 | printf("%d ", d[i]); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Quick-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_ELEMENT_COUNT 1000000 5 | 6 | using namespace std; 7 | 8 | int d[MAX_ELEMENT_COUNT]; 9 | 10 | void qsort(int l, int r) 11 | { 12 | if (l < r) 13 | { 14 | int x = d[r]; 15 | int j = l - 1; 16 | 17 | for (int i = l; i <= r; i++) 18 | { 19 | if (d[i] <= x) 20 | { 21 | j++; 22 | int temp = d[i]; 23 | d[i] = d[j]; 24 | d[j] = temp; 25 | } 26 | } 27 | 28 | qsort(l, j - 1); 29 | qsort(j + 1, r); 30 | } 31 | } 32 | 33 | int main() 34 | { 35 | for (int i = 0; i < MAX_ELEMENT_COUNT; i++) 36 | { 37 | d[i] = rand(); 38 | } 39 | 40 | qsort(0, MAX_ELEMENT_COUNT - 1); 41 | 42 | for (int i = 0; i < MAX_ELEMENT_COUNT; i++) 43 | { 44 | printf("%d\n", d[i]); 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Radix-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ELEMENT_COUNT 100000 4 | 5 | using namespace std; 6 | 7 | int n, d[ELEMENT_COUNT]; 8 | int pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 }; 9 | 10 | void radix_sort() 11 | { 12 | static int c[10], _d[ELEMENT_COUNT]; 13 | for (int k = 0; k < 8; k++) 14 | { 15 | for (int i = 0; i < 10; i++) 16 | { 17 | c[i] = 0; 18 | } 19 | for (int i = 0; i < n; i++) 20 | { 21 | c[d[i] / pow10[k] % 10]++; 22 | } 23 | for (int i = 1; i < 10; i++) 24 | { 25 | c[i] += c[i - 1]; 26 | } 27 | for (int i = n - 1; i >= 0; i--) 28 | { 29 | _d[--c[d[i] / pow10[k] % 10]] = d[i]; 30 | } 31 | for (int i = 0; i < n; i++) 32 | { 33 | d[i] = _d[i]; 34 | } 35 | } 36 | } 37 | 38 | int main() 39 | { 40 | scanf("%d", &n); 41 | for (int i = 0; i < n; i++) 42 | { 43 | scanf("%d", &d[i]); 44 | } 45 | radix_sort(); 46 | for (int i = 0; i < n; i++) 47 | { 48 | printf("%d ", d[i]); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Reverse-Pair(Merge-Sort).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define INF 1000000000 4 | #define ELEMENT_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | int n, d[ELEMENT_COUNT], ans; 9 | 10 | void merge(int o1, int l1, int o2, int l2) 11 | { 12 | static int a1[ELEMENT_COUNT], a2[ELEMENT_COUNT]; 13 | int k1 = 0, k2 = 0; 14 | for (int i = 0; i < l1; i++) 15 | { 16 | a1[i] = d[i + o1]; 17 | } 18 | a1[l1] = INF; 19 | for (int i = 0; i < l2; i++) 20 | { 21 | a2[i] = d[i + o2]; 22 | } 23 | a2[l2] = INF; 24 | for (int i = 0; i < l1 + l2; i++) 25 | { 26 | if (a1[k1] <= a2[k2]) 27 | { 28 | d[i + o1] = a1[k1++]; 29 | } 30 | else 31 | { 32 | d[i + o1] = a2[k2++]; 33 | ans += (l1 - k1); 34 | } 35 | } 36 | } 37 | 38 | void merge_sort(int l, int r) 39 | { 40 | if (l < r) 41 | { 42 | int mid = (l + r) >> 1; 43 | merge_sort(l, mid); 44 | merge_sort(mid + 1, r); 45 | merge(l, mid - l + 1, mid + 1, r - mid); 46 | } 47 | } 48 | 49 | int main() 50 | { 51 | scanf("%d", &n); 52 | for (int i = 0; i < n; i++) 53 | { 54 | scanf("%d", &d[i]); 55 | } 56 | merge_sort(0, n - 1); 57 | printf("%d", ans); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Segment-Direction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct point 6 | { 7 | int x, y; 8 | }; 9 | 10 | struct segment 11 | { 12 | point begin, end; 13 | }; 14 | 15 | int direction(segment &base, segment &s) 16 | { 17 | return (s.end.x - s.begin.x) * (base.end.y - base.begin.y) - (base.end.x - base.begin.x) * (s.end.y - s.begin.y); 18 | } 19 | 20 | int main() 21 | { 22 | while (true) 23 | { 24 | segment base, s; 25 | scanf("%d%d%d%d%d%d%d%d", &base.begin.x, &base.begin.y, &base.end.x, &base.end.y, &s.begin.x, &s.begin.y, &s.end.x, &s.end.y); 26 | printf("%d\n", direction(base, s)); 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Segment-Intersection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct point 6 | { 7 | double x, y; 8 | point() { } 9 | point(double _x, double _y) : x(_x), y(_y) { } 10 | }; 11 | 12 | struct segment 13 | { 14 | point s, t; 15 | segment() { } 16 | segment(point _s, point _t) : s(_s), t(_t) { } 17 | }s[110]; 18 | 19 | double cross(segment base, segment x) 20 | { 21 | return (base.s.x - base.t.x) * (x.s.y - x.t.y) - (base.s.y - base.t.y) * (x.s.x - x.t.x); 22 | } 23 | 24 | bool segment_intersect(segment x, segment y) 25 | { 26 | return cross(x, segment(x.s, y.s)) * cross(x, segment(x.s, y.t)) <= 0 && cross(y, segment(y.s, x.s)) * cross(y, segment(y.s, x.t)) <= 0; 27 | } 28 | 29 | int main() 30 | { 31 | int m; 32 | while (true) 33 | { 34 | scanf("%d", &m); 35 | if (m == 0) 36 | { 37 | break; 38 | } 39 | for (int i = 0; i < m; i++) 40 | { 41 | scanf("%lf%lf%lf%lf", &s[i].s.x, &s[i].s.y, &s[i].t.x, &s[i].t.y); 42 | } 43 | int ans = 0; 44 | for (int i = 0; i < m; i++) 45 | { 46 | for (int j = 0; j < i; j++) 47 | { 48 | if (segment_intersect(s[i], s[j]) == true) 49 | { 50 | ans++; 51 | } 52 | } 53 | } 54 | printf("%d\n", ans); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Segment-Tree(Minimum).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct node 6 | { 7 | int l, r, min, lazy; 8 | }T[4000010]; 9 | 10 | int d[1000010]; 11 | 12 | inline int min(int x, int y) 13 | { 14 | return x < y ? x : y; 15 | } 16 | 17 | void build_tree(int l, int r, int k) 18 | { 19 | T[k].l = l; 20 | T[k].r = r; 21 | if (l == r) 22 | { 23 | T[k].min = d[l]; 24 | } 25 | else 26 | { 27 | int mid = (l + r) >> 1; 28 | build_tree(l, mid, k << 1); 29 | build_tree(mid + 1, r, (k << 1) + 1); 30 | T[k].min = min(T[k << 1].min, T[(k << 1) + 1].min); 31 | } 32 | } 33 | 34 | int delta; 35 | void update(int l, int r, int k) 36 | { 37 | if (T[k].l == l && T[k].r == r) 38 | { 39 | T[k].lazy += delta; 40 | T[k].min += delta; 41 | } 42 | else 43 | { 44 | int mid = (T[k].l + T[k].r) >> 1; 45 | if (r <= mid) 46 | { 47 | update(l, r, k << 1); 48 | } 49 | else if (l > mid) 50 | { 51 | update(l, r, (k << 1) + 1); 52 | } 53 | else 54 | { 55 | update(l, mid, k << 1); 56 | update(mid + 1, r, (k << 1) + 1); 57 | } 58 | T[k].min = min(T[k << 1].min, T[(k << 1) + 1].min); 59 | } 60 | } 61 | 62 | int query(int l, int r, int k) 63 | { 64 | if (T[k].l == l && T[k].r == r) 65 | { 66 | return T[k].min; 67 | } 68 | else 69 | { 70 | int mid = (T[k].l + T[k].r) >> 1, res; 71 | T[k << 1].lazy += T[k].lazy; 72 | T[k << 1].min += T[k].lazy; 73 | T[(k << 1) + 1].lazy += T[k].lazy; 74 | T[(k << 1) + 1].min += T[k].lazy; 75 | T[k].lazy = 0; 76 | if (r <= mid) 77 | { 78 | res = query(l, r, k << 1); 79 | } 80 | else if (l > mid) 81 | { 82 | res = query(l, r, (k << 1) + 1); 83 | } 84 | else 85 | { 86 | res = min(query(l, mid, k << 1), query(mid + 1, r, (k << 1) + 1)); 87 | } 88 | T[k].min = min(T[k << 1].min, T[(k << 1) + 1].min); 89 | return res; 90 | } 91 | } 92 | 93 | int main() 94 | { 95 | int n; 96 | scanf("%d", &n); 97 | for (int i = 1; i <= n; i++) 98 | { 99 | scanf("%d", &d[i]); 100 | } 101 | build_tree(1, n, 1); 102 | while (true) 103 | { 104 | int o, a, b, d; 105 | scanf("%d", &o); 106 | switch (o) 107 | { 108 | case 1: 109 | scanf("%d%d", &a, &b); 110 | printf("%d\n", query(a, b, 1)); 111 | break; 112 | case 2: 113 | scanf("%d%d%d", &a, &b, &d); 114 | delta = d; 115 | update(a, b, 1); 116 | break; 117 | } 118 | } 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /Segment-Tree(Sum).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ELEMENT_COUNT 200000 4 | 5 | using namespace std; 6 | 7 | struct node 8 | { 9 | int l, r; 10 | long long sum, lazy; 11 | }T[ELEMENT_COUNT * 4]; 12 | 13 | int n, q; 14 | int d[ELEMENT_COUNT]; 15 | 16 | void build_tree(int l, int r, int k) 17 | { 18 | T[k].l = l; 19 | T[k].r = r; 20 | if (l == r) 21 | { 22 | T[k].sum = d[l]; 23 | } 24 | else 25 | { 26 | int mid = (l + r) >> 1; 27 | build_tree(l, mid, k << 1); 28 | build_tree(mid + 1, r, (k << 1) + 1); 29 | T[k].sum = T[k << 1].sum + T[(k << 1) + 1].sum; 30 | } 31 | } 32 | 33 | long long get_sum(int l, int r, int k) 34 | { 35 | if (l == T[k].l && r == T[k].r) 36 | { 37 | return T[k].sum + T[k].lazy * (r - l + 1); 38 | } 39 | else 40 | { 41 | T[k].sum += T[k].lazy * (T[k].r - T[k].l + 1); 42 | T[k << 1].lazy += T[k].lazy; 43 | T[(k << 1) + 1].lazy += T[k].lazy; 44 | T[k].lazy = 0; 45 | if (r <= T[k << 1].r) 46 | { 47 | return get_sum(l, r, k << 1); 48 | } 49 | else if (l >= T[(k << 1) + 1].l) 50 | { 51 | return get_sum(l, r, (k << 1) + 1); 52 | } 53 | else 54 | { 55 | return get_sum(l, T[k << 1].r, k << 1) + get_sum(T[(k << 1) + 1].l, r, (k << 1) + 1); 56 | } 57 | } 58 | } 59 | 60 | long long delta; 61 | void update_segment(int l, int r, int k) 62 | { 63 | if (l == T[k].l && r == T[k].r) 64 | { 65 | T[k].lazy += delta; 66 | } 67 | else 68 | { 69 | T[k].sum += delta * (r - l + 1); 70 | if (r <= T[k << 1].r) 71 | { 72 | update_segment(l, r, k << 1); 73 | } 74 | else if (l >= T[(k << 1) + 1].l) 75 | { 76 | update_segment(l, r, (k << 1) + 1); 77 | } 78 | else 79 | { 80 | update_segment(l, T[k << 1].r, k << 1); 81 | update_segment(T[(k << 1) + 1].l, r, (k << 1) + 1); 82 | } 83 | } 84 | } 85 | 86 | int main() 87 | { 88 | scanf("%d", &n); 89 | for (int i = 0; i < n; i++) 90 | { 91 | scanf("%d", &d[i]); 92 | } 93 | build_tree(0, n - 1, 1); 94 | scanf("%d", &q); 95 | while (q--) 96 | { 97 | int o, a, b; 98 | long long d; 99 | scanf("%d", &o); 100 | switch (o) 101 | { 102 | case 1: 103 | scanf("%d%d%lld", &a, &b, &d); 104 | delta = d; 105 | update_segment(a - 1, b - 1, 1); 106 | break; 107 | case 2: 108 | scanf("%d%d", &a, &b); 109 | printf("%lld\n", get_sum(a - 1, b - 1, 1)); 110 | break; 111 | case 3: 112 | for (int i = 0; i < n * 2; i++) 113 | { 114 | printf("%2d ", i); 115 | } 116 | printf("\n"); 117 | for (int i = 0; i < n * 2; i++) 118 | { 119 | printf("%2lld ", T[i].lazy); 120 | } 121 | printf("\n"); 122 | break; 123 | default: 124 | printf("Instruction incorrect!\n"); 125 | } 126 | } 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /Selection-Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX_ELEMENT_COUNT 1000 4 | 5 | int n, d[MAX_ELEMENT_COUNT]; 6 | 7 | void selection_sort() { 8 | for (int i = 0; i < n; i++) { 9 | int minv = d[i], minp = i; 10 | for (int j = i + 1; j < n; j++) { 11 | if (d[j] < minv) { 12 | minv = d[j]; 13 | minp = j; 14 | } 15 | } 16 | int t = d[i]; 17 | d[i] = minv; 18 | d[minp] = t; 19 | } 20 | } 21 | 22 | int main() { 23 | scanf("%d", &n); 24 | for (int i = 0; i < n; i++) { 25 | scanf("%d", d + i); 26 | } 27 | selection_sort(); 28 | for (int i = 0; i < n; i++) { 29 | printf("%d ", d[i]); 30 | } 31 | printf("\n"); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Selection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ELEMENT_COUNT 10000 4 | 5 | using namespace std; 6 | 7 | int n, k, d[ELEMENT_COUNT]; 8 | 9 | int partition(int l, int r) 10 | { 11 | int x = d[r], j = l - 1; 12 | for (int i = l; i <= r; i++) 13 | { 14 | if (d[i] <= x) 15 | { 16 | j++; 17 | int temp = d[i]; 18 | d[i] = d[j]; 19 | d[j] = temp; 20 | } 21 | } 22 | return j + 1; 23 | } 24 | 25 | int select(int k) 26 | { 27 | int l = 0, r = n - 1; 28 | while (l < r) 29 | { 30 | int ord = partition(l, r); 31 | if (ord < k) 32 | { 33 | l = ord; 34 | } 35 | else if (ord > k) 36 | { 37 | r = ord - 2; 38 | } 39 | else 40 | { 41 | return d[ord - 1]; 42 | } 43 | } 44 | return d[l]; 45 | } 46 | 47 | int main() 48 | { 49 | scanf("%d%d", &n, &k); 50 | for (int i = 0; i < n; i++) 51 | { 52 | scanf("%d", &d[i]); 53 | } 54 | int kth = select(k); 55 | printf("%d", kth); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Shell-Sort(Shell's-Gap-Sequence).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ELEMENT_COUNT 100000 4 | 5 | using namespace std; 6 | 7 | int n, d[ELEMENT_COUNT]; 8 | 9 | void Shell_sort() 10 | { 11 | for (int gc = n >> 1; gc >= 1; gc >>= 1) 12 | { 13 | for (int s = 0; s < gc; s++) 14 | { 15 | for (int i = s; i < n; i += gc) 16 | { 17 | for (int j = i - gc; j >= 0 && d[j] > d[j + gc]; j -= gc) 18 | { 19 | int temp = d[j]; 20 | d[j] = d[j + gc]; 21 | d[j + gc] = temp; 22 | } 23 | } 24 | } 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | scanf("%d", &n); 31 | for (int i = 0; i < n; i++) 32 | { 33 | scanf("%d", &d[i]); 34 | } 35 | Shell_sort(); 36 | for (int i = 0; i < n; i++) 37 | { 38 | printf("%d ", d[i]); 39 | } 40 | printf("\n"); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /Sieve-of-Eratosthenes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX 100 5 | 6 | using namespace std; 7 | 8 | bool isprime[MAX + 1]; 9 | 10 | int main() 11 | { 12 | memset(isprime, true, sizeof(isprime)); 13 | for (int i = 2; i * i <= MAX; i++) 14 | { 15 | if (isprime[i] == true) 16 | { 17 | for (int j = i * i; j <= MAX; j += i) 18 | { 19 | isprime[j] = false; 20 | } 21 | } 22 | } 23 | for (int i = 2; i < MAX; i++) 24 | { 25 | if (isprime[i] == true) 26 | { 27 | printf("%d\n", i); 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Singly-Linked-List(Pointer).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | 5 | using namespace std; 6 | 7 | struct node 8 | { 9 | int id, value; 10 | node *next; 11 | }; 12 | 13 | node *head; 14 | 15 | void insert(int id, int value) 16 | { 17 | node *o = new node; 18 | o->next = head; 19 | head = o; 20 | o->id = id; 21 | o->value = value; 22 | } 23 | 24 | int find(int id) 25 | { 26 | node *cur = head; 27 | while (cur != NIL) 28 | { 29 | if (cur->id == id) 30 | { 31 | return cur->value; 32 | } 33 | cur = cur->next; 34 | } 35 | return -1; 36 | } 37 | 38 | bool del(int id) 39 | { 40 | if (head == NIL) 41 | { 42 | return false; 43 | } 44 | if (head->id == id) 45 | { 46 | node *temp = head; 47 | head = head->next; 48 | delete temp; 49 | return true; 50 | } 51 | node *prev = head, *cur = head->next; 52 | while (cur != NIL) 53 | { 54 | if (cur->id == id) 55 | { 56 | prev->next = cur->next; 57 | delete cur; 58 | return true; 59 | } 60 | prev = cur; 61 | cur = cur->next; 62 | } 63 | return false; 64 | } 65 | 66 | int main() 67 | { 68 | int in, id, value; 69 | while (true) 70 | { 71 | scanf("%d", &in); 72 | if (in == 1) 73 | { 74 | scanf("%d%d", &id, &value); 75 | insert(id, value); 76 | } 77 | else if (in == 2) 78 | { 79 | scanf("%d", &id); 80 | printf("%d\n", find(id)); 81 | } 82 | else if (in == 3) 83 | { 84 | scanf("%d", &id); 85 | printf("%s\n", del(id) == true ? "deleted" : "failed"); 86 | } 87 | else if (in == 0) 88 | { 89 | return 0; 90 | } 91 | else 92 | { 93 | printf("No such command!\n"); 94 | } 95 | } 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /Skip-List.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NIL 0 5 | #define LAYER_COUNT 20 6 | #define NODE_COUNT 100000 7 | 8 | using namespace std; 9 | 10 | struct node 11 | { 12 | int id, value; 13 | node *next, *lower; 14 | node(); 15 | }; 16 | 17 | node::node() : next(NIL) { } 18 | 19 | node *head[LAYER_COUNT]; 20 | 21 | void init() 22 | { 23 | head[0] = new node; 24 | for (int i = 1; i < LAYER_COUNT; i++) 25 | { 26 | head[i] = new node; 27 | head[i]->lower = head[i - 1]; 28 | } 29 | } 30 | 31 | void insert(int id, int value) 32 | { 33 | int k = 0; 34 | while ((rand() & 1) == 0) 35 | { 36 | k++; 37 | } 38 | node *prev = head[k], *cur = head[k], *upper = NIL; 39 | for (; k >= 0; k--) 40 | { 41 | while (cur != NIL && cur->id < id) 42 | { 43 | prev = cur; 44 | cur = cur->next; 45 | } 46 | node *o = new node; 47 | o->next = cur; 48 | o->id = id; 49 | o->value = value; 50 | prev->next = o; 51 | prev = prev->lower; 52 | cur = prev; 53 | if (upper != NIL) 54 | { 55 | upper->lower = o; 56 | } 57 | upper = o; 58 | } 59 | } 60 | 61 | int find(int id) 62 | { 63 | node *prev, *cur = head[LAYER_COUNT - 1]; 64 | for (int k = LAYER_COUNT - 1; k >= 0; k--) 65 | { 66 | while (cur != NIL && cur->id < id) 67 | { 68 | prev = cur; 69 | cur = cur->next; 70 | } 71 | if (cur != NIL && cur->id == id) 72 | { 73 | return cur->value; 74 | } 75 | else 76 | { 77 | prev = prev->lower; 78 | cur = prev; 79 | } 80 | } 81 | return -1; 82 | } 83 | 84 | void debug() 85 | { 86 | for (int i = 5; i >= 0; i--) 87 | { 88 | node *cur = head[i]; 89 | printf("head[%d]", i); 90 | while (cur != NIL) 91 | { 92 | printf(" -> (%d, %d)", cur->id, cur->value); 93 | cur = cur->next; 94 | } 95 | printf("\n"); 96 | } 97 | } 98 | 99 | int main() 100 | { 101 | int in, id, value; 102 | init(); 103 | while (true) 104 | { 105 | scanf("%d", &in); 106 | if (in == 1) 107 | { 108 | scanf("%d%d", &id, &value); 109 | insert(id, value); 110 | } 111 | else if (in == 2) 112 | { 113 | scanf("%d", &id); 114 | printf("%d\n", find(id)); 115 | } 116 | else if (in == 4) 117 | { 118 | debug(); 119 | } 120 | else if (in == 0) 121 | { 122 | return 0; 123 | } 124 | else 125 | { 126 | printf("No such command!\n"); 127 | } 128 | } 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /Sparse-Table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, m; 6 | int st[1000010][21], pow2[21]; 7 | 8 | inline int max(int x, int y) 9 | { 10 | return x > y ? x : y; 11 | } 12 | 13 | inline int _log2(int x) 14 | { 15 | int res = 0; 16 | while (x > 1) 17 | { 18 | x >>= 1; 19 | res++; 20 | } 21 | return res; 22 | } 23 | 24 | void init_pow2() 25 | { 26 | pow2[0] = 1; 27 | for (int i = 1; i <= 20; i++) 28 | { 29 | pow2[i] = pow2[i - 1] * 2; 30 | } 31 | } 32 | 33 | void build_st() 34 | { 35 | init_pow2(); 36 | for (int i = 1; i <= 20; i++) 37 | { 38 | for (int j = 0; j < n; j++) 39 | { 40 | st[j][i] = max(st[j][i - 1], st[j + pow2[i - 1]][i - 1]); 41 | } 42 | } 43 | } 44 | 45 | int get_max(int l, int r) 46 | { 47 | int x = _log2(r - l + 1); 48 | return max(st[l][x], st[r - pow2[x] + 1][x]); 49 | } 50 | 51 | int main() 52 | { 53 | scanf("%d%d", &n, &m); 54 | for (int i = 0; i < n; i++) 55 | { 56 | scanf("%d", &st[i][0]); 57 | } 58 | build_st(); 59 | for (int i = 0; i < m; i++) 60 | { 61 | int a, b; 62 | scanf("%d%d", &a, &b); 63 | printf("%d\n", get_max(a - 1, b - 1)); 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Splay(Single-Rotation).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | 5 | using namespace std; 6 | 7 | struct node 8 | { 9 | int key, value; 10 | node *ch[2]; 11 | node(int _key = 0, int _value = 0) : key(_key), value(_value) { ch[0] = ch[1] = NIL; } 12 | }*root; 13 | 14 | void rotate(node *&u, int dir) 15 | { 16 | node *o = u->ch[dir]; 17 | u->ch[dir] = o->ch[dir ^ 1]; 18 | o->ch[dir ^ 1] = u; 19 | u = o; 20 | } 21 | 22 | void insert(node *&u, int key, int value) 23 | { 24 | if (u == NIL) 25 | { 26 | u = new node(key, value); 27 | return; 28 | } 29 | if (key < u->key) 30 | { 31 | insert(u->ch[0], key, value); 32 | rotate(u, 0); 33 | } 34 | else if (key > u->key) 35 | { 36 | insert(u->ch[1], key, value); 37 | rotate(u, 1); 38 | } 39 | } 40 | 41 | int find(node *&u, int key) 42 | { 43 | if (u == NIL) 44 | { 45 | return -1; 46 | } 47 | if (u->key == key) 48 | { 49 | return u->value; 50 | } 51 | int res; 52 | if (key < u->key) 53 | { 54 | res = find(u->ch[0], key); 55 | if (u->ch[0] != NIL) 56 | rotate(u, 0); 57 | } 58 | else if (key > u->key) 59 | { 60 | res = find(u->ch[1], key); 61 | if (u->ch[1] != NIL) 62 | rotate(u, 1); 63 | } 64 | return res; 65 | } 66 | 67 | int main() 68 | { 69 | int in, key, value; 70 | while (true) 71 | { 72 | scanf("%d", &in); 73 | if (in == 1) 74 | { 75 | scanf("%d%d", &key, &value); 76 | insert(root, key, value); 77 | } 78 | else if (in == 2) 79 | { 80 | scanf("%d", &key); 81 | printf("%d\n", find(root, key)); 82 | } 83 | else if (in == 0) 84 | { 85 | return 0; 86 | } 87 | else 88 | { 89 | printf("No such command!\n"); 90 | } 91 | } 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /Splay-with-Parent(Array).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | #define ELEMENT_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | int ch[ELEMENT_COUNT][2], fa[ELEMENT_COUNT], key[ELEMENT_COUNT], size[ELEMENT_COUNT], use = 0, root; 9 | 10 | inline int which(int u) 11 | { 12 | return ch[fa[u]][0] == u ? 0 : 1; 13 | } 14 | 15 | inline void update(int u) 16 | { 17 | size[u] = size[ch[u][0]] + size[ch[u][1]] + 1; 18 | } 19 | 20 | void rotate(int u) 21 | { 22 | int p = fa[u]; 23 | int q = fa[p]; 24 | int uk = which(u), pk = which(p); 25 | int c = ch[u][uk ^ 1]; 26 | fa[c] = p; 27 | fa[u] = q; 28 | fa[p] = u; 29 | ch[p][uk] = ch[u][uk ^ 1]; 30 | ch[u][uk ^ 1] = p; 31 | ch[q][pk] = u; 32 | update(p); 33 | update(u); 34 | } 35 | 36 | void splay(int u, int tar) 37 | { 38 | while (fa[u] != tar) 39 | { 40 | if (fa[fa[u]] != tar) 41 | { 42 | if (which(u) == which(fa[u])) rotate(fa[u]); 43 | else rotate(u); 44 | } 45 | rotate(u); 46 | } 47 | if (tar == 0) root = u; 48 | } 49 | 50 | int cmp(int ikey, int ukey) 51 | { 52 | return ikey < ukey ? 0 : 1; 53 | } 54 | 55 | void insert(int ikey) 56 | { 57 | if (root == NIL) root = ++use, ch[use][0] = ch[use][1] = fa[use] = NIL, key[use] = ikey; 58 | else 59 | { 60 | int u = root; 61 | while (key[u] != ikey) 62 | { 63 | int k = cmp(ikey, key[u]); 64 | if (k == -1) break; 65 | if (ch[u][k] == NIL) ch[u][k] = ++use, fa[use] = u, key[use] = ikey; 66 | u = ch[u][k]; 67 | } 68 | splay(u, 0); 69 | } 70 | } 71 | 72 | int find(int fkey) 73 | { 74 | int u = root; 75 | while (u != NIL) 76 | { 77 | if (key[u] == fkey) return 1; 78 | else u = ch[u][cmp(fkey, key[u])]; 79 | } 80 | return 0; 81 | } 82 | 83 | int main() 84 | { 85 | int op, x; 86 | while (true) 87 | { 88 | scanf("%d%d", &op, &x); 89 | if (op == 1) 90 | { 91 | insert(x); 92 | } 93 | else if (op == 2) 94 | { 95 | splay(x, 0); 96 | } 97 | else if (op == 3) 98 | { 99 | printf("find result = %d\n", find(x)); 100 | } 101 | else if (op == 0) 102 | { 103 | break; 104 | } 105 | else 106 | { 107 | printf("No such command!\n"); 108 | } 109 | } 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /Splay.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NIL 0 4 | 5 | using namespace std; 6 | 7 | struct node 8 | { 9 | int key, value; 10 | node *ch[2]; 11 | node(int _key = 0, int _value = 0) : key(_key), value(_value) { ch[0] = ch[1] = NIL; } 12 | }*root; 13 | 14 | void rotate(node *&u, int dir) 15 | { 16 | node *o = u->ch[dir]; 17 | u->ch[dir] = o->ch[dir ^ 1]; 18 | o->ch[dir ^ 1] = u; 19 | u = o; 20 | } 21 | 22 | inline int compare(node *u, int key) 23 | { 24 | if (key == u->key) 25 | { 26 | return -1; 27 | } 28 | return key < u->key ? 0 : 1; 29 | } 30 | 31 | void insert(node *&u, int key, int value) 32 | { 33 | if (u == NIL) 34 | { 35 | u = new node(key, value); 36 | return; 37 | } 38 | int k0 = compare(u, key); 39 | if (k0 == -1) 40 | { 41 | return; 42 | } 43 | if (u->ch[k0] == NIL) 44 | { 45 | u->ch[k0] = new node(key, value); 46 | } 47 | else 48 | { 49 | int k1 = compare(u->ch[k0], key); 50 | if (k1 == -1) 51 | { 52 | return; 53 | } 54 | insert(u->ch[k0]->ch[k1], key, value); 55 | if (k0 == k1) 56 | { 57 | rotate(u, k0); 58 | } 59 | else 60 | { 61 | rotate(u->ch[k0], k1); 62 | } 63 | } 64 | rotate(u, k0); 65 | } 66 | 67 | int find(node *&u, int key) 68 | { 69 | if (u == NIL) 70 | { 71 | return -1; 72 | } 73 | int k0 = compare(u, key); 74 | if (k0 == -1) 75 | { 76 | return u->value; 77 | } 78 | if (u->ch[k0] == NIL) 79 | { 80 | return -1; 81 | } 82 | else 83 | { 84 | int k1 = compare(u->ch[k0], key), res; 85 | if (k1 == -1) 86 | { 87 | res = u->ch[k0]->value; 88 | goto END; 89 | } 90 | res = find(u->ch[k0]->ch[k1], key); 91 | if (u->ch[k0]->ch[k1] != NIL) 92 | { 93 | if (k0 == k1) 94 | { 95 | rotate(u, k0); 96 | } 97 | else 98 | { 99 | rotate(u->ch[k0], k1); 100 | } 101 | } 102 | END: 103 | rotate(u, k0); 104 | return res; 105 | } 106 | } 107 | 108 | int main() 109 | { 110 | int in, key, value; 111 | while (true) 112 | { 113 | scanf("%d", &in); 114 | if (in == 1) 115 | { 116 | scanf("%d%d", &key, &value); 117 | insert(root, key, value); 118 | } 119 | else if (in == 2) 120 | { 121 | scanf("%d", &key); 122 | printf("%d\n", find(root, key)); 123 | } 124 | else if (in == 0) 125 | { 126 | return 0; 127 | } 128 | else 129 | { 130 | printf("No such command!\n"); 131 | } 132 | } 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /Sprague-Grundy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int k, s[100], sg[10001]; 7 | bool has[10001]; 8 | 9 | void init_sg() 10 | { 11 | sg[0] = 0; 12 | for (int i = 1; i <= 10000; i++) 13 | { 14 | memset(has, false, sizeof(has)); 15 | for (int j = 0; j < k; j++) 16 | { 17 | if (i - s[j] >= 0) 18 | { 19 | has[sg[i - s[j]]] = true; 20 | } 21 | } 22 | for (int j = 0; ; j++) 23 | { 24 | if (has[j] == false) 25 | { 26 | sg[i] = j; 27 | break; 28 | } 29 | } 30 | } 31 | } 32 | 33 | int main() 34 | { 35 | while (true) 36 | { 37 | scanf("%d", &k); 38 | if (k == 0) 39 | { 40 | break; 41 | } 42 | for (int i = 0; i < k; i++) 43 | { 44 | scanf("%d", &s[i]); 45 | } 46 | init_sg(); 47 | int t, c, x, res; 48 | scanf("%d", &t); 49 | while (t--) 50 | { 51 | res = 0; 52 | scanf("%d", &c); 53 | while (c--) 54 | { 55 | scanf("%d", &x); 56 | res ^= sg[x]; 57 | } 58 | if (res == 0) 59 | { 60 | printf("L"); 61 | } 62 | else 63 | { 64 | printf("W"); 65 | } 66 | } 67 | printf("\n"); 68 | } 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define ELEMENT_COUNT 100000 5 | 6 | using namespace std; 7 | 8 | // Requirement: every element in stack must be positive. 9 | // Otherwise, M[0] should be set to -INF. 10 | int S[ELEMENT_COUNT], M[ELEMENT_COUNT]; 11 | int sp = 1; 12 | 13 | void push(int x) 14 | { 15 | S[sp] = x; 16 | if (x > M[sp - 1]) 17 | { 18 | M[sp] = x; 19 | } 20 | else 21 | { 22 | M[sp] = M[sp - 1]; 23 | } 24 | sp++; 25 | } 26 | 27 | int pop() 28 | { 29 | return S[--sp]; 30 | } 31 | 32 | bool empty() 33 | { 34 | return sp == 1; 35 | } 36 | 37 | int get_max() 38 | { 39 | return M[sp - 1]; 40 | } 41 | 42 | int main() 43 | { 44 | while (true) 45 | { 46 | char o[10]; 47 | int a; 48 | scanf(" %s", o); 49 | if (strcmp(o, "push") == 0) 50 | { 51 | scanf("%d", &a); 52 | push(a); 53 | } 54 | else if (strcmp(o, "pop") == 0) 55 | { 56 | printf("%d\n", pop()); 57 | } 58 | else if (strcmp(o, "getmax") == 0) 59 | { 60 | printf("%d\n", get_max()); 61 | } 62 | else if (strcmp(o, "abort") == 0) 63 | { 64 | return 0; 65 | } 66 | else 67 | { 68 | printf("No such instruction.\n"); 69 | } 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Stirling-Number(Cycle,Unsigned,Recursion).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, su[100][100]; 6 | 7 | void init_su() 8 | { 9 | for (int i = 1; i <= n; i++) 10 | { 11 | su[i][0] = 0; 12 | su[0][i] = 0; 13 | } 14 | su[0][0] = 1; 15 | for (int i = 1; i <= n; i++) 16 | { 17 | for (int j = 1; j <= n; j++) 18 | { 19 | su[i][j] = su[i - 1][j - 1] + su[i - 1][j] * (i - 1); 20 | } 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | scanf("%d", &n); 27 | init_su(); 28 | for (int i = 0; i <= n; i++) 29 | { 30 | for (int j = 0; j <= i; j++) 31 | { 32 | printf("%5d ", su[i][j]); 33 | } 34 | printf("\n"); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Stirling-Number(Subset,Recursion).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int n, S[100][100]; 6 | 7 | void init_S() 8 | { 9 | for (int i = 1; i <= n; i++) 10 | { 11 | S[i][0] = 0; 12 | S[0][i] = 0; 13 | } 14 | S[0][0] = 1; 15 | for (int i = 1; i <= n; i++) 16 | { 17 | for (int j = 1; j <= i; j++) 18 | { 19 | S[i][j] = S[i - 1][j - 1] + S[i - 1][j] * j; 20 | } 21 | } 22 | } 23 | 24 | int main() 25 | { 26 | scanf("%d", &n); 27 | init_S(); 28 | for (int i = 0; i <= n; i++) 29 | { 30 | for (int j = 0; j <= i; j++) 31 | { 32 | printf("%5d ", S[i][j]); 33 | } 34 | printf("\n"); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Suffix-Array(Doubling).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define STRING_LENGTH 100000 5 | 6 | using namespace std; 7 | 8 | struct sortinfo 9 | { 10 | int x, y, ord; 11 | }; 12 | 13 | int l; 14 | char s[STRING_LENGTH]; 15 | int rank[STRING_LENGTH * 2], sa[STRING_LENGTH]; 16 | 17 | void radix_sort(sortinfo *d) 18 | { 19 | static sortinfo _d[STRING_LENGTH], res[STRING_LENGTH]; 20 | static int c[STRING_LENGTH]; 21 | memset(c, 0, sizeof(c)); 22 | for (int i = 0; i < l; i++) 23 | { 24 | c[d[i].y]++; 25 | } 26 | for (int i = 1; i <= l; i++) 27 | { 28 | c[i] += c[i - 1]; 29 | } 30 | for (int i = l - 1; i >= 0; i--) 31 | { 32 | _d[--c[d[i].y]] = d[i]; 33 | } 34 | memset(c, 0, sizeof(c)); 35 | for (int i = 0; i < l; i++) 36 | { 37 | c[_d[i].x]++; 38 | } 39 | for (int i = 1; i <= l; i++) 40 | { 41 | c[i] += c[i - 1]; 42 | } 43 | for (int i = l - 1; i >= 0; i--) 44 | { 45 | res[--c[_d[i].x]] = _d[i]; 46 | } 47 | for (int i = 0; i < l; i++) 48 | { 49 | d[i] = res[i]; 50 | } 51 | } 52 | 53 | void init_rank() 54 | { 55 | static int c[256]; 56 | static sortinfo d[STRING_LENGTH]; 57 | int x = 1; 58 | for (int i = 0; i < l; i++) 59 | { 60 | c[(int)s[i]] = 1; 61 | } 62 | for (int i = 0; i < 256; i++) 63 | { 64 | if (c[i] == 1) 65 | { 66 | c[i] = x++; 67 | } 68 | } 69 | for (int i = 0; i < l; i++) 70 | { 71 | rank[i] = c[(int)s[i]]; 72 | } 73 | for (int k = 1; k < l; k <<= 1) 74 | { 75 | for (int i = 0; i < l; i++) 76 | { 77 | d[i].x = rank[i]; 78 | d[i].y = rank[i + k]; 79 | d[i].ord = i; 80 | } 81 | radix_sort(d); 82 | x = 1; 83 | rank[d[0].ord] = 1; 84 | for (int i = 1; i < l; i++) 85 | { 86 | rank[d[i].ord] = (d[i].x == d[i - 1].x && d[i].y == d[i - 1].y ? x : ++x); 87 | } 88 | if (x == l) 89 | { 90 | break; 91 | } 92 | } 93 | } 94 | 95 | void rank_to_sa() 96 | { 97 | for (int i = 0; i < l; i++) 98 | { 99 | sa[rank[i] - 1] = i + 1; 100 | } 101 | } 102 | 103 | int main() 104 | { 105 | scanf("%d%s", &l, s); 106 | init_rank(); 107 | rank_to_sa(); 108 | for (int i = 0; i < l; i++) 109 | { 110 | printf("%d\n", sa[i]); 111 | } 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /Suffix-Array-with-Height(Doubling).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define STRING_LENGTH 200000 5 | 6 | using namespace std; 7 | 8 | struct sortinfo 9 | { 10 | int x, y, ord; 11 | }; 12 | 13 | int l; 14 | char s[STRING_LENGTH]; 15 | int rank[STRING_LENGTH * 2], sa[STRING_LENGTH], height[STRING_LENGTH]; 16 | 17 | void radix_sort(sortinfo *d) 18 | { 19 | static sortinfo _d[STRING_LENGTH], res[STRING_LENGTH]; 20 | static int c[STRING_LENGTH]; 21 | memset(c, 0, sizeof(c)); 22 | for (int i = 0; i < l; i++) 23 | { 24 | c[d[i].y]++; 25 | } 26 | for (int i = 1; i <= l; i++) 27 | { 28 | c[i] += c[i - 1]; 29 | } 30 | for (int i = l - 1; i >= 0; i--) 31 | { 32 | _d[--c[d[i].y]] = d[i]; 33 | } 34 | memset(c, 0, sizeof(c)); 35 | for (int i = 0; i < l; i++) 36 | { 37 | c[_d[i].x]++; 38 | } 39 | for (int i = 1; i <= l; i++) 40 | { 41 | c[i] += c[i - 1]; 42 | } 43 | for (int i = l - 1; i >= 0; i--) 44 | { 45 | res[--c[_d[i].x]] = _d[i]; 46 | } 47 | for (int i = 0; i < l; i++) 48 | { 49 | d[i] = res[i]; 50 | } 51 | } 52 | 53 | void init_rank() 54 | { 55 | static int c[256]; 56 | static sortinfo d[STRING_LENGTH]; 57 | int x = 1; 58 | for (int i = 0; i < l; i++) 59 | { 60 | c[(int)s[i]] = 1; 61 | } 62 | for (int i = 0; i < 256; i++) 63 | { 64 | if (c[i] == 1) 65 | { 66 | c[i] = x++; 67 | } 68 | } 69 | for (int i = 0; i < l; i++) 70 | { 71 | rank[i] = c[(int)s[i]]; 72 | } 73 | for (int k = 1; k < l; k <<= 1) 74 | { 75 | for (int i = 0; i < l; i++) 76 | { 77 | d[i].x = rank[i]; 78 | d[i].y = rank[i + k]; 79 | d[i].ord = i; 80 | } 81 | radix_sort(d); 82 | x = 1; 83 | rank[d[0].ord] = 1; 84 | for (int i = 1; i < l; i++) 85 | { 86 | rank[d[i].ord] = (d[i].x == d[i - 1].x && d[i].y == d[i - 1].y ? x : ++x); 87 | } 88 | if (x == l) 89 | { 90 | break; 91 | } 92 | } 93 | } 94 | 95 | void rank_to_sa() 96 | { 97 | for (int i = 0; i < l; i++) 98 | { 99 | sa[rank[i]] = i; 100 | } 101 | } 102 | 103 | void init_height() 104 | { 105 | int k = 0; 106 | for (int i = 0; i < l; i++) 107 | { 108 | if (k > 0) 109 | { 110 | k--; 111 | } 112 | if (rank[i] == l) 113 | { 114 | continue; 115 | } 116 | for (; s[i + k] == s[sa[rank[i] + 1] + k]; k++) ; 117 | height[rank[i]] = k; 118 | } 119 | } 120 | 121 | int main() 122 | { 123 | scanf("%s", s); 124 | l = strlen(s); 125 | init_rank(); 126 | rank_to_sa(); 127 | init_height(); 128 | for (int i = 1; i <= l; i++) 129 | { 130 | printf("%d ", sa[i] + 1); 131 | } 132 | printf("\n"); 133 | for (int i = 1; i < l; i++) 134 | { 135 | printf("%d ", height[i]); 136 | } 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /Suffix-Automaton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NIL 0 5 | #define ALPHABET_SIZE 26 6 | 7 | using namespace std; 8 | 9 | struct node 10 | { 11 | node *next[ALPHABET_SIZE], *parent; 12 | int len; 13 | node(int _len = 0) : len(_len) { memset(next, 0, sizeof(next)), parent = NIL; } 14 | }*root, *last; 15 | 16 | char s[100000]; 17 | int len; 18 | 19 | void init() 20 | { 21 | root = new node(0); 22 | last = root; 23 | } 24 | 25 | void extend(int x) 26 | { 27 | node *p = last; 28 | node *np = new node(p->len + 1); 29 | while (p != NIL && p->next[x] == NIL) 30 | { 31 | p->next[x] = np; 32 | p = p->parent; 33 | } 34 | if (p == NIL) 35 | { 36 | np->parent = root; 37 | } 38 | else 39 | { 40 | node *q = p->next[x]; 41 | if (q->len == p->len + 1) 42 | { 43 | np->parent = q; 44 | } 45 | else 46 | { 47 | node *nq = new node; 48 | *nq = *q; 49 | nq->len = p->len + 1; 50 | q->parent = np->parent = nq; 51 | while (p != NIL && p->next[x] == q) 52 | { 53 | p->next[x] = nq; 54 | p = p->parent; 55 | } 56 | } 57 | } 58 | last = np; 59 | } 60 | 61 | int main() 62 | { 63 | scanf("%s", s); 64 | len = strlen(s); 65 | init(); 66 | for (int i = 0; i < len; i++) 67 | { 68 | extend(s[i] - 'a'); 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Tarjan(Strongly-Connected-Components).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct vertex 8 | { 9 | int first_edge, dfn, low, col; 10 | bool instack; 11 | }V[100010]; 12 | 13 | struct edge 14 | { 15 | int endp, next; 16 | }E[500010]; 17 | 18 | struct res 19 | { 20 | vector block; 21 | }*R; 22 | 23 | int ec = 1, ivc, iec, dfn = 1, col = 1; 24 | int S[100000], sp = 0; 25 | 26 | void push(int x) 27 | { 28 | V[x].instack = true; 29 | S[sp++] = x; 30 | } 31 | 32 | int pop() 33 | { 34 | V[S[sp - 1]].instack = false; 35 | return S[--sp]; 36 | } 37 | 38 | void add_edge(int u, int v) 39 | { 40 | E[ec].next = V[u].first_edge; 41 | V[u].first_edge = ec; 42 | E[ec].endp = v; 43 | ec++; 44 | } 45 | 46 | void DFS(int u) 47 | { 48 | V[u].dfn = V[u].low = dfn++; 49 | push(u); 50 | for (int cur = V[u].first_edge; cur != 0; cur = E[cur].next) 51 | { 52 | if (V[E[cur].endp].dfn == 0) 53 | { 54 | DFS(E[cur].endp); 55 | } 56 | if (V[E[cur].endp].instack == true && V[E[cur].endp].low < V[u].low) 57 | { 58 | V[u].low = V[E[cur].endp].low; 59 | } 60 | } 61 | if (V[u].low == V[u].dfn) 62 | { 63 | int x = pop(); 64 | while (x != u) 65 | { 66 | V[x].col = col; 67 | x = pop(); 68 | } 69 | V[x].col = col; 70 | col++; 71 | } 72 | } 73 | 74 | bool _res_cmp(res x, res y) 75 | { 76 | return x.block[0] < y.block[0]; 77 | } 78 | 79 | int main() 80 | { 81 | int u, v; 82 | scanf("%d%d", &ivc, &iec); 83 | for (int i = 0; i < iec; i++) 84 | { 85 | scanf("%d%d", &u, &v); 86 | add_edge(u, v); 87 | } 88 | for (int i = 1; i <= ivc; i++) 89 | { 90 | if (V[i].dfn == 0) 91 | { 92 | DFS(i); 93 | } 94 | } 95 | R = new res[col + 1]; 96 | for (int i = 1; i <= ivc; i++) 97 | { 98 | R[V[i].col].block.push_back(i); 99 | } 100 | sort(R + 1, R + col, _res_cmp); 101 | for (int i = 1; i < col; i++) 102 | { 103 | printf("%d", R[i].block[0]); 104 | for (int j = 1; j < R[i].block.size(); j++) 105 | { 106 | printf(" %d", R[i].block[j]); 107 | } 108 | printf("\n"); 109 | } 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /Treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NIL 0 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | node *ch[2]; 11 | int key, pr; 12 | node(int _key = 0, int _pr = 0) : key(_key), pr(_pr) { ch[0] = ch[1] = NIL; } 13 | }*root; 14 | 15 | void rotate(node *&u, int dir) 16 | { 17 | node *o = u->ch[dir]; 18 | u->ch[dir] = o->ch[dir ^ 1]; 19 | o->ch[dir ^ 1] = u; 20 | u = o; 21 | } 22 | 23 | int cmp(int ikey, int ukey) 24 | { 25 | if (ikey == ukey) 26 | return -1; 27 | return ikey < ukey ? 0 : 1; 28 | } 29 | 30 | void insert(node *&u, int key, int pr) 31 | { 32 | if (u == NIL) 33 | { 34 | u = new node(key, pr); 35 | } 36 | else 37 | { 38 | int k = cmp(key, u->key); 39 | if (k == -1) 40 | { 41 | return; 42 | } 43 | insert(u->ch[k], key, pr); 44 | if (u->ch[k]->pr > u->pr) 45 | { 46 | rotate(u, k); 47 | } 48 | } 49 | } 50 | 51 | int find(node *u, int key) 52 | { 53 | if (u == NIL) 54 | { 55 | return -1; 56 | } 57 | else 58 | { 59 | int k = cmp(key, u->key); 60 | if (k == -1) 61 | { 62 | return 1; 63 | } 64 | return find(u->ch[k], key); 65 | } 66 | } 67 | 68 | int main() 69 | { 70 | int in, key; 71 | while (true) 72 | { 73 | scanf("%d", &in); 74 | if (in == 1) 75 | { 76 | scanf("%d", &key); 77 | insert(root, key, rand()); 78 | } 79 | else if (in == 2) 80 | { 81 | scanf("%d", &key); 82 | printf("%d\n", find(root, key)); 83 | } 84 | else if (in == 0) 85 | { 86 | break; 87 | } 88 | else 89 | { 90 | printf("No such command!\n"); 91 | } 92 | } 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /Trie(Array).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define TRIE_SIZE 100000 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | int cnt; 11 | int next[26]; 12 | }T[TRIE_SIZE]; 13 | 14 | int nc = 2; 15 | 16 | void insert(char *s) 17 | { 18 | int len = strlen(s), cur = 1; 19 | for (int i = 0; i < len; i++) 20 | { 21 | if (T[cur].next[s[i]] == 0) 22 | { 23 | T[cur].next[s[i]] = nc; 24 | cur = nc; 25 | nc++; 26 | } 27 | else 28 | { 29 | cur = T[cur].next[s[i]]; 30 | } 31 | } 32 | T[cur].cnt++; 33 | } 34 | 35 | int query(char *s) 36 | { 37 | int len = strlen(s), cur = 1; 38 | for (int i = 0; i < len; i++) 39 | { 40 | if (T[cur].next[s[i]] == 0) 41 | { 42 | return 0; 43 | } 44 | else 45 | { 46 | cur = T[cur].next[s[i]]; 47 | } 48 | } 49 | return T[cur].cnt; 50 | } 51 | 52 | int main() 53 | { 54 | int o; 55 | char s[100]; 56 | while (true) 57 | { 58 | scanf("%d%s", &o, s); 59 | if (o == 1) 60 | { 61 | insert(s); 62 | } 63 | else if (o == 2) 64 | { 65 | printf("%d\n", query(s)); 66 | } 67 | else 68 | { 69 | printf("No such command!\n"); 70 | } 71 | } 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Trie(Pointer).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NIL 0 5 | 6 | using namespace std; 7 | 8 | struct node 9 | { 10 | int info; 11 | node *next[26]; 12 | }; 13 | 14 | node root; 15 | 16 | void insert(char *s) 17 | { 18 | int l = strlen(s); 19 | node *cur = &root; 20 | for (int i = 0; i < l; i++) 21 | { 22 | if (cur->next[s[i] - 'a'] == NIL) 23 | { 24 | node *o = new node; 25 | o->info = 0; 26 | cur->next[s[i] - 'a'] = o; 27 | } 28 | cur = cur->next[s[i] - 'a']; 29 | } 30 | cur->info++; 31 | } 32 | 33 | int find(char *s) 34 | { 35 | int l = strlen(s); 36 | node *cur = &root; 37 | for (int i = 0; i < l; i++) 38 | { 39 | if (cur->next[s[i] - 'a'] == NIL) 40 | { 41 | return -1; 42 | } 43 | else 44 | { 45 | cur = cur->next[s[i] - 'a']; 46 | } 47 | } 48 | return cur->info; 49 | } 50 | 51 | int main() 52 | { 53 | int in; 54 | char str[100]; 55 | while (true) 56 | { 57 | scanf("%d", &in); 58 | if (in == 1) 59 | { 60 | scanf("%s", str); 61 | insert(str); 62 | } 63 | else if (in == 2) 64 | { 65 | scanf("%s", str); 66 | printf("%d\n", find(str)); 67 | } 68 | else if (in == 0) 69 | { 70 | return 0; 71 | } 72 | else 73 | { 74 | printf("No such command!\n"); 75 | } 76 | } 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Algorithms 2 | 3 |   这里有各种算法的C++代码,任何人可以在自己的任何程序中使用。欢迎大家指出代码中的错误以及有待改进的地方。 4 | 5 |   本仓库内所有代码的授权方式为The Unlicense。大家如果使用我的代码开发自己的软件挣了大钱,或是参考我的代码在信息学奥林匹克竞赛中获得金牌,我都会很高兴的。使用这里的代码之后,你可以自主选择是否公开源代码。总而言之,你可以把这里的代码当作你自己写的一样,无论怎样使用都是被允许的。但是,我不对本仓库内代码的正确性负责。大家要是使用我的代码开发软件而导致程序崩溃,或是参考我的代码在考试时出错,请不要向我抱怨。如果你愿意,遇到问题可以在Issues中提出来,我们共同解决。 6 | 7 |   本仓库有两个分支,master和candidate。master用于存放原作者自己编写的代码,candidate接受所有合理的Pull Request。 8 | 9 |   以下索引提供了本仓库内算法的中文名,方便大家查找。此列表更新可能有较长时间的延迟,不保证所有已提交算法的名称都在列表中出现。 10 | ## *Index* 11 | | --------------------------Contents-------------------------- | --------------------------FileName-------------------------- | 12 | | ------------------------------------------------------------ | ------------------------------------------------------------ | 13 | | 2-SAT可满足性 | 2-Satisfiability | 14 | | AC自动机 | Aho-Corasick-Automaton | 15 | | 单源最短路径(SPFA) | Bellman-Ford(Queue-Optimised) | 16 | | 单源最短路径(Bellman-Ford) | Bellman-Ford | 17 | | 双连通分量 | Biconnected-Compotent | 18 | | 使用Edmonds-Karp进行二分图匹配 | Bigrpah-Matching(Edmonds-Karp) | 19 | | 使用ISAP算法进行二分图匹配 | Bigraph-Matching(Improved-Shortest-Augmenting-Path) | 20 | | 普通的二叉搜索树 | Binary-Search-Tree | 21 | | 广度优先搜索 | Breadth-First-Search | 22 | | 冒泡排序 | Bubble-Sort | 23 | | 桶排序 | Bucket-Sort | 24 | | 笛卡尔树 | Cartesian-Tree | 25 | | 求解多边形的重心 | Centre-of-Gravity(Polygon) | 26 | | 组合数的递推求解 | Combination(Recursion) | 27 | | 枚举组合 | Combination | 28 | | 基本的复数类 | Complex-Number | 29 | | 割点 | Cut-Vertex | 30 | | 深度优先搜索 | Depth-First-Search | 31 | | 堆优化的Dijkstra算法 | Dijkstra(Heap-Optimised) | 32 | | Dinic最大流算法 | Dinic | 33 | | 并查集 | Disjoint-Set-Union | 34 | | 最大流Edmonds-Karp算法 | Edmonds-Karp | 35 | | 欧拉函数的线性筛法 | Euler's-Totient-Function(Linear) | 36 | | 欧拉函数 | Euler's-Totient-Function | 37 | | 有向图的欧拉回路 | Eulerian-Tour(Digraph) | 38 | | 拓展欧几里得算法 | Extended-Euclid | 39 | | 快速幂 | Fast-Exponentiation | 40 | | 快速数论变换(NTT) | Fast-Number-Theoretic-Transform | 41 | | 树状数组 | Fenwick-Tree | 42 | | 斐波那契堆 | Fibonacci-Heap | 43 | | 所有结点对之间的最短路径(Floyd) | Floyd-Warshall | 44 | | 高斯消元 | Gaussian-Elimination | 45 | | 凸包算法(Graham扫描法) | Graham-Scan | 46 | | 辗转相除法求最大公约数 | Greatest-Common-Divisor | 47 | | 堆排序 | Heap-Sort | 48 | | 树链剖分(轻重链剖分) | Heavy-Light-Decomposition | 49 | | 高精度类 | High-Precision(Integer) | 50 | | 匈牙利算法 | Hungarian-Algorithm | 51 | | 具有gap优化的ISAP算法 | Improved-Shortest-Augmenting-Path(Gap-Optimised) | 52 | | 朴素的ISAP算法 | Improved-Shortest-Augmenting-Path(Naive) | 53 | | 插入排序 | Insertion-Sort | 54 | | K-D树 | K-Dimensional-Tree | 55 | | KMP算法 | Knuth-Morris-Pratt | 56 | | Kruskal算法 | Kruskal | 57 | | 最近公共祖先(Tarjan) | Least-Common-Ancestor(Tarjan) | 58 | | 左偏树 | Leftist-Tree | 59 | | 线性基 | Linear-Basis | 60 | | LCT | Link-Cut-Tree | 61 | | LCT(带翻转) | Link-Cut-Tree(with-Reverse) | 62 | | 使用后缀数组求解最长公共子串 | Longest-Common-Substring | 63 | | 最长上升子序列(n·log(n)) | Longest-Increasing-Subsequence(n·log(n)) | 64 | | 倍增法求最近公共祖先 | Lowest-Common-Ancestor(Doubling) | 65 | | 朴素的矩阵乘法 | Matrix-Multiplication(Naive) | 66 | | 归并排序 | Merge-Sort | 67 | | Miller-Rabin素数测试 | Miller-Rabin | 68 | | 最小堆 | Min-Heap | 69 | | 阶乘的乘法逆元线性筛 | Modular-Multiplicative-Inverse(Factorial,Linear) | 70 | | 乘法逆元线性筛 | Modular-Multiplicative-Inverse(Linear) | 71 | | 乘法逆元 | Modular-Multiplicative-Inverse | 72 | | 无旋式Treap | Non-Rotating-Treap | 73 | | 回文树 | Palindromic-Tree | 74 | | 枚举排列 | Permutation | 75 | | 可持久化数组 | Persistent-Array | 76 | | 仅支持单点修改的可持久化线段树(维护区间和值) | Persistent-Segment-Tree(Sum) | 77 | | 可持久化Treap | Persistent-Treap | 78 | | 可持久化Trie | Persistent-Trie | 79 | | Prim算法 | Prim | 80 | | 试除法素数测试 | Prime-Check(Naive) | 81 | | 线性的素数筛法 | Prime-Sieve(Linear) | 82 | | 原根 | Primitive-Root | 83 | | Prüfer序列 | Prüfer-Sequence(Tree-to-Sequence) | 84 | | 队列的基本操作 | Queue | 85 | | 快速排序的优化版本 | Quick-Sort(Extra-Optimised) | 86 | | 快速排序的随机化版本 | Quick-Sort(Randomized) | 87 | | 快速排序 | Quick-Sort | 88 | | 基数排序 | Radix-Sort | 89 | | 使用归并排序求逆序对个数 | Reverse-Pair(Merge-Sort) | 90 | | 使用向量叉积判断两个有向线段的时针关系 | Segment-Direction | 91 | | 求两个线段的交点 | Segment-Intersection | 92 | | 线段树维护区间最小值 | Segment-Tree(Minimum) | 93 | | 线段树维护区间和值 | Segment-Tree(Sum) | 94 | | 选择排序 | Selection-Sort | 95 | | 普通的选择算法 | Selection | 96 | | 希尔排序 | Shell-Sort(Shell's-Gap-Sequence) | 97 | | Eratosthenes素数筛法 | Sieve-of-Erotosthenes | 98 | | 指针版的单向链表 | Singly-Linked-List(Pointer) | 99 | | 跳表 | Skip-List | 100 | | ST表 | Sparse-Table | 101 | | 记录父结点的伸展树 | Splay-with-Parent(Array) | 102 | | 伸展树 | Splay | 103 | | 单旋“伸展树” | Splay(Single-Rotation) | 104 | | 博弈论SG函数 | Sprague-Grundy | 105 | | 栈的基本操作 | Stack | 106 | | 递推法求解无符号第一类斯特林数 | Stirling-Number(Cycle,Unsigned,Recursion) | 107 | | 递推法求解第二类斯特林数 | Stirling-Number(Subset,Recursion) | 108 | | 倍增法求解后缀数组 | Suffix-Array(Doubling) | 109 | | 倍增法求解后缀数组(附带Height数组) | Suffix-Array-with-Height(Doubling) | 110 | | 后缀自动机 | Suffix-Automaton | 111 | | 使用Tarjan算法求解强连通分量 | Tarjan(Strongly-Connected-Components) | 112 | | Treap | Treap | 113 | | 数组版的字典树 | Trie(Array) | 114 | | 指针版的字典树 | Trie(Pointer) | 115 | --------------------------------------------------------------------------------