├── .gitignore ├── graph_theory ├── articfind │ ├── sample_output_articfind_1.txt │ ├── sample_output_articfind_2.txt │ ├── sample_input_articfind_1.txt │ ├── sample_input_articfind_2.txt │ └── find_articulation_point.cc ├── kruskal │ ├── sample_input_kruskal.txt │ └── kruskal.cc ├── hierholzer │ ├── sample_input_hierholzer.txt │ ├── sample_input_hierholzer_graphic.bmp │ └── hierholzer.cc ├── ford_fulkerson │ ├── sample_input_ford_fulkerson_capacity_scaling.txt │ └── ford_fulkerson_capacity_scaling.cc ├── floyd_warshall │ ├── sample_input_floyd_warshall.txt │ └── floyd_warshall.cc ├── prim │ ├── sample_input_prim.txt │ ├── prim_O(nlogn).cc │ └── prim_O(n^2).cc ├── bfs │ ├── sample_input_bfs.txt │ └── bfs.cc ├── implement_graph │ └── implement_graph.cc ├── dijkstra │ ├── dijkstra_O(nlogn)_vector_nopqclass.cc │ ├── dijkstra_O(nlogn)_list.cc │ ├── dijkstra_O(nlogn)_vector.cc │ └── dijkstra_O(n**2).cc ├── toposort │ └── toposort.cc ├── dfs │ ├── dfs_vector.cc │ └── dfs.cc ├── connected_components │ └── connected_components.cc ├── dinic │ └── dinic.cc └── edmonds_karp │ ├── edmonds_karp_adjacency_matrix.cc │ └── edmonds_karp_adjacency_lists.cc ├── data_structure ├── suffix_array │ ├── sample_input_suffix_array.txt │ ├── suffix_array_programming_contest_approach.pdf │ └── suffix_array.cc ├── segment_tree │ ├── sample_input_segment_tree_add_intervals.txt │ ├── segment_tree_RMQ.cc │ └── segment_tree_add_intervals.cc ├── binary_search_tree │ ├── sample_input_binary_search_tree.cc │ └── binary_search_tree.cc ├── stack │ ├── stack_stl.cc │ └── stack.c ├── queue │ ├── queue_stl.cc │ └── queue.c ├── priority_queue │ └── priority_queue_stl.cc ├── set │ └── set.cc ├── heap │ └── heap.cc ├── binary_indexed_tree │ ├── 2d_binary_indexed_tree.cc │ └── binary_indexed_tree.cc ├── dictionary │ └── dictionary.cc ├── linked_list │ └── linked_list.c └── union_find │ └── union-find.cc ├── combinatorics ├── next_permutation │ ├── sample_input_next_permutation.txt │ ├── next_permutation_stl.cc │ └── next_permutation.cc ├── all_subset │ ├── all_subset_int_v2.cc │ └── all_subset_int.cc └── all_permutation │ ├── all_permutation_string.cc │ └── all_permutation_int.cc ├── computational_geometry ├── convex_hull │ ├── sample_input_convex_hull.txt │ └── convexhull.cc ├── line_line_intersection │ └── line_line_intersection.cc └── closest_pair │ └── closest_pair.cc ├── algebra ├── gcd_lcm │ ├── gcd_iterative.cc │ └── gcd_lcm.cc ├── linear_congruence │ └── linear_congruence.cc ├── prime_factorization │ └── prime_factorization.cc ├── prime_generator │ └── prime_generator.cc └── bignum │ ├── prog_challenges │ ├── bignum_nosignbit.cc │ └── bignum.cc │ └── bignum.cc ├── dynamic_programming ├── LCS │ ├── lcs_length_inefficient.cc │ ├── subseq.cc │ ├── lcs_length_iterative.cc │ ├── lcs.cc │ └── lcs_length_efficient.cc ├── LIS │ ├── LIS_quadratic.cc │ └── LIS_nlogn.cc ├── MCM │ └── matrix_chain_multiplication.cc ├── RMQ │ └── RMQ_sparse_table.cc ├── edit_distance │ └── edit_dist.cc └── MER │ ├── maximum_empty_rectangle.cc │ └── maximum_empty_rectangle_brute_force.cc ├── sorting ├── radixsort │ └── radixsort.cc ├── qsort │ ├── qsort.cc │ └── sample_input_qsort.txt └── mergesort │ ├── mergesort.cc │ └── sample_input_mergesort.txt ├── LICENSE.md ├── string_handling ├── kmp │ └── kmp.cc └── c_string_functions │ └── c_string_functions.c └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | a.out 2 | *~ -------------------------------------------------------------------------------- /graph_theory/articfind/sample_output_articfind_1.txt: -------------------------------------------------------------------------------- 1 | 2 3 4 2 | -------------------------------------------------------------------------------- /graph_theory/articfind/sample_output_articfind_2.txt: -------------------------------------------------------------------------------- 1 | 0 1 6 2 | -------------------------------------------------------------------------------- /data_structure/suffix_array/sample_input_suffix_array.txt: -------------------------------------------------------------------------------- 1 | bananana 2 | -------------------------------------------------------------------------------- /combinatorics/next_permutation/sample_input_next_permutation.txt: -------------------------------------------------------------------------------- 1 | 11 2 | 3 4 1 3 0 3 9 7 4 2 1 3 | -------------------------------------------------------------------------------- /graph_theory/kruskal/sample_input_kruskal.txt: -------------------------------------------------------------------------------- 1 | 4 5 2 | 1 2 10 3 | 2 3 15 4 | 1 3 5 5 | 4 2 2 6 | 4 3 40 7 | -------------------------------------------------------------------------------- /data_structure/segment_tree/sample_input_segment_tree_add_intervals.txt: -------------------------------------------------------------------------------- 1 | 1 5 2 | 3 7 3 | 2 6 4 | 0 8 5 | 2 4 6 | -------------------------------------------------------------------------------- /graph_theory/articfind/sample_input_articfind_1.txt: -------------------------------------------------------------------------------- 1 | 7 8 2 | 0 6 3 | 0 2 4 | 2 6 5 | 3 2 6 | 1 3 7 | 3 4 8 | 4 1 9 | 5 4 10 | -------------------------------------------------------------------------------- /graph_theory/hierholzer/sample_input_hierholzer.txt: -------------------------------------------------------------------------------- 1 | 1 4 2 | 5 1 3 | 4 3 4 | 7 3 5 | 5 7 6 | 6 7 7 | 5 6 8 | 2 5 9 | 2 7 10 | 2 6 11 | 2 4 12 | 6 4 13 | -------------------------------------------------------------------------------- /data_structure/binary_search_tree/sample_input_binary_search_tree.cc: -------------------------------------------------------------------------------- 1 | 6 2 | 2 3 | 7 4 | 1 5 | 4 6 | 8 7 | 3 8 | 15 9 | 12 10 | 18 11 | 13 12 | 19 13 | 22 14 | -------------------------------------------------------------------------------- /graph_theory/hierholzer/sample_input_hierholzer_graphic.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ippeb/ACM-ICPC/HEAD/graph_theory/hierholzer/sample_input_hierholzer_graphic.bmp -------------------------------------------------------------------------------- /graph_theory/ford_fulkerson/sample_input_ford_fulkerson_capacity_scaling.txt: -------------------------------------------------------------------------------- 1 | 4 5 2 | 0 3 3 | 0 1 100000000 4 | 0 2 100000000 5 | 2 1 1 6 | 1 3 100000000 7 | 2 3 100000000 8 | -------------------------------------------------------------------------------- /graph_theory/articfind/sample_input_articfind_2.txt: -------------------------------------------------------------------------------- 1 | 10 13 2 | 8 9 3 | 6 7 4 | 4 5 5 | 0 1 6 | 1 2 7 | 6 8 8 | 7 9 9 | 4 6 10 | 5 6 11 | 0 4 12 | 0 5 13 | 1 3 14 | 2 3 15 | -------------------------------------------------------------------------------- /data_structure/suffix_array/suffix_array_programming_contest_approach.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ippeb/ACM-ICPC/HEAD/data_structure/suffix_array/suffix_array_programming_contest_approach.pdf -------------------------------------------------------------------------------- /graph_theory/floyd_warshall/sample_input_floyd_warshall.txt: -------------------------------------------------------------------------------- 1 | 8 13 2 | 1 2 10 3 | 1 3 100 4 | 2 3 20 5 | 2 4 8 6 | 3 4 70 7 | 4 5 60 8 | 3 5 50 9 | 1 6 800 10 | 3 6 1 11 | 6 8 100 12 | 7 8 90 13 | 7 5 60 14 | 7 6 500 15 | -------------------------------------------------------------------------------- /computational_geometry/convex_hull/sample_input_convex_hull.txt: -------------------------------------------------------------------------------- 1 | 18 2 | 1 1 3 | 1 1 4 | 2 2 5 | 0 9 6 | 0 8 7 | 7 4 8 | 0 0 9 | 10 2 10 | 4 0 11 | -5 1 12 | -5 2 13 | -5 4 14 | 7 5 15 | 7 2 16 | -3 6 17 | 17 3 18 | 7 4 19 | 2 2 20 | -------------------------------------------------------------------------------- /graph_theory/prim/sample_input_prim.txt: -------------------------------------------------------------------------------- 1 | 8 16 2 | 1 2 10 3 | 1 3 11 4 | 1 4 100 5 | 1 5 33 6 | 1 6 77 7 | 2 3 20 8 | 2 4 8 9 | 3 4 70 10 | 4 5 60 11 | 3 5 50 12 | 1 6 800 13 | 3 6 1 14 | 6 8 100 15 | 7 8 90 16 | 7 5 60 17 | 7 6 500 18 | -------------------------------------------------------------------------------- /graph_theory/bfs/sample_input_bfs.txt: -------------------------------------------------------------------------------- 1 | 20 20 2 | 1 2 3 | 1 3 4 | 3 5 5 | 3 4 6 | 2 6 7 | 2 7 8 | 6 8 9 | 8 9 10 | 7 5 11 | 4 5 12 | 10 12 13 | 20 20 14 | 19 5 15 | 19 20 16 | 3 2 17 | 2 16 18 | 14 13 19 | 16 15 20 | 12 11 21 | 9 9 22 | 13 13 23 | -------------------------------------------------------------------------------- /algebra/gcd_lcm/gcd_iterative.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Greatest Common Divisor (iterative). 3 | 4 | Copyright 2015 Josef Ziegler 5 | */ 6 | 7 | int gcd(int a, int b) { 8 | while (b) b ^= a ^= b ^= a %= b; 9 | return a; 10 | } 11 | 12 | int main() { 13 | } 14 | -------------------------------------------------------------------------------- /algebra/gcd_lcm/gcd_lcm.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Greatest Common Divisor and Least Common Multiple. 3 | 4 | Copyright 2015 Josef Ziegler 5 | */ 6 | 7 | int gcd(int a, int b) { 8 | if (b == 0) return a; 9 | return gcd(b, a%b); 10 | } 11 | 12 | int lcm(int a, int b) { 13 | return (a*b) / gcd(a, b); 14 | } 15 | 16 | int main() { 17 | } 18 | -------------------------------------------------------------------------------- /dynamic_programming/LCS/lcs_length_inefficient.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Longest Common Subsequence Length (LCS), (inefficient). 3 | 4 | Very inefficient, recursive LCS, O(2^n). 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | int lcs_length(char * A, char * B) 11 | { 12 | if (*A == '\0' || *B == '\0') return 0; 13 | else if (*A == *B) return 1 + lcs_length(A+1, B+1); 14 | else return max(lcs_length(A+1,B), lcs_length(A,B+1)); 15 | } 16 | 17 | int main(){ 18 | char a[1000],b[1000]; 19 | scanf("%s %s",a,b); 20 | printf("%d\n",lcs_length(a,b)); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /dynamic_programming/LCS/subseq.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Subsequence Checker. 3 | 4 | Is string a (pattern) a subsequence of string b (text)? 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | #define FALSE 0 13 | #define TRUE 1 14 | using namespace std; 15 | 16 | int subseq(char * P, char * T) 17 | { 18 | while (*T != '\0') 19 | if (*P == *T++ && *++P == '\0') 20 | return TRUE; 21 | return FALSE; 22 | } 23 | 24 | int main(){ 25 | char a[1000],b[1000]; 26 | scanf("%s %s",&a,&b); 27 | printf("%d\n",subseq(a,b)); 28 | } 29 | -------------------------------------------------------------------------------- /data_structure/stack/stack_stl.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Stack (STL). 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | stack S; 13 | 14 | int main(){ 15 | printf("insert numbers, stop with -1\n"); 16 | int m; 17 | do{ 18 | scanf("%d",&m); 19 | S.push(m); 20 | }while (m!=-1); 21 | printf("number of items: %d\n",S.size()); 22 | printf("insert number of items to pop and print: "); 23 | scanf("%d",&m); 24 | int i; 25 | for (i=0; i 11 | #include 12 | using namespace std; 13 | 14 | void all_subsets(string& S, int l) { 15 | if (l == 0) { 16 | cout << S << endl; 17 | return; 18 | } 19 | 20 | for (int i = 0; i < 2; i++) { 21 | S[l] = i + '0'; 22 | all_subsets(S, l-1); 23 | } 24 | } 25 | 26 | int main() { 27 | int l; 28 | cin >> l; 29 | string tmp(""); 30 | tmp.resize(l+1); 31 | all_subsets(tmp, l); 32 | } 33 | -------------------------------------------------------------------------------- /data_structure/queue/queue_stl.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Queue (STL). 3 | 4 | Using STL queue. 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | queue Q; 15 | 16 | int main(){ 17 | printf("stop by inserting -1 at the end\n"); 18 | printf("insert:\n"); 19 | int m; 20 | do{ 21 | scanf("%d",&m); 22 | Q.push(m); 23 | }while(m!=-1); 24 | printf("number of elements (including -1): %d\n",Q.size()); 25 | printf("first and last element: %d, %d\n",Q.front(), Q.back()); 26 | printf("remove and print number of elements:"); 27 | int x,i; 28 | scanf("%d",&x); 29 | for (i=0;i 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | struct cmp{ 14 | bool operator()(int a, int b){ 15 | return a,cmp> P; 19 | 20 | int main(){ 21 | printf("insert some values, enter -1 to quit\n"); 22 | int m; 23 | do{ 24 | scanf("%d",&m); 25 | P.push(m); 26 | } while (m!=-1); 27 | printf("number of elements: %d\n",P.size()); 28 | printf("how many elements do you want to pop: "); 29 | scanf("%d",&m); 30 | printf("\n"); 31 | for (int i=0; i 16 | #include 17 | using namespace std; 18 | 19 | int main(){ 20 | int l; 21 | scanf("%d", &l); 22 | int *A = new int[l]; 23 | for (int i = 0; i < l; i++) 24 | scanf("%d", &A[i]); 25 | 26 | do{ 27 | for (int i=0; i 9 | #include 10 | using namespace std; 11 | 12 | set S; 13 | set::iterator iter; 14 | 15 | int main(){ 16 | printf("insert some numbers, stop with -1\n"); 17 | int m; 18 | while(1){ 19 | fscanf(stdin,"%d",&m); 20 | S.insert(m); 21 | if (m==-1) 22 | break; 23 | } 24 | printf("number of distinct elements: %d\n",S.size()); 25 | for (iter=S.begin(); iter!=S.end(); iter++) 26 | printf("%d\n",*iter); 27 | printf("element to erase: "); 28 | putchar(10); 29 | scanf("%d",&m); 30 | if (S.count(m)) 31 | S.erase(S.find(m)); 32 | else 33 | printf("not found"); 34 | putchar(10); 35 | for (iter=S.begin(); iter!=S.end(); iter++) 36 | printf("%d\n",*iter); 37 | } 38 | -------------------------------------------------------------------------------- /combinatorics/all_permutation/all_permutation_string.cc: -------------------------------------------------------------------------------- 1 | /* 2 | All permutation (string). 3 | 4 | Constructs all permutations of a given input string via backtracking. 5 | Note that repetitions occur if there are letters in the input string 6 | that appear more than once. 7 | 8 | (c) 2015 Josef Ziegler 9 | 10 | */ 11 | 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | void permute(string& S, int at) { 17 | if (at == S.length()) 18 | cout << S << endl; 19 | 20 | for (int i = at; i < S.length(); i++) { 21 | char tmp = S[at]; 22 | S[at]=S[i]; 23 | S[i]=tmp; 24 | permute(S, at + 1); 25 | S[i]=S[at]; // two lines only needed if we pass 26 | S[at]=tmp; // S as a reference 27 | } 28 | } 29 | 30 | 31 | int main() { 32 | string tmp; 33 | cin >> tmp; 34 | permute(tmp, 0); 35 | } 36 | -------------------------------------------------------------------------------- /sorting/radixsort/radixsort.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Radixsort. 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #define MAX 100 10 | 11 | void radixsort(int *a, int n) { 12 | int b[MAX], m = a[0], exp = 1; 13 | for (int i = 0; i < n; i++) 14 | if (a[i] > m) 15 | m = a[i]; 16 | 17 | while (m / exp > 0) { 18 | int bucket[10] = { 0 }; 19 | 20 | for (int i = 0; i < n; i++) 21 | bucket[(a[i] / exp) % 10]++; 22 | 23 | for (int i = 1; i < 10; i++) 24 | bucket[i] += bucket[i - 1]; 25 | 26 | for (int i = n - 1; i >= 0; i--) 27 | b[--bucket[(a[i] / exp) % 10]] = a[i]; 28 | 29 | for (int i = 0; i < n; i++) 30 | a[i] = b[i]; 31 | exp *= 10; 32 | } 33 | } 34 | 35 | int main() { 36 | int a[8] = {170, 45, 75, 90, 802, 24, 2, 66}; 37 | radixsort(a, 8); 38 | for (int i = 0; i < 8; i++) 39 | printf("%d ", a[i]); 40 | } 41 | -------------------------------------------------------------------------------- /algebra/linear_congruence/linear_congruence.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Extendend GCD, Linear Congruence. 3 | 4 | Computes gcd(p, q) and x, y such that p * x + q * y = gcd(p, q), 5 | x, y, p, q are integers. 6 | 7 | (c) 2015 Josef Ziegler 8 | 9 | */ 10 | 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | int gcd(int p, int q, int& x, int& y){ 16 | int x1,y1; /* previous coefficients */ 17 | int g; /* value of gcd(p,q) */ 18 | if (q>p) return (gcd(q, p, y, x)); 19 | if (q==0){ 20 | x = 1; 21 | y = 0; 22 | return(p);} 23 | g = gcd(q, p%q, x1, y1); 24 | x = y1; 25 | y = x1 - floor(p/q)*y1; 26 | return g; 27 | } 28 | 29 | int main(){ 30 | int p, q, x, y, g, tmp; 31 | while (1){ 32 | scanf("%d",&p); 33 | scanf("%d",&q); 34 | if (p 16 | #include 17 | using namespace std; 18 | 19 | void prime_factorization(int x, int* factor, int& l){ 20 | l= 0; 21 | while (x%2 == 0){ 22 | x /= 2; 23 | factor[l++] = 2; 24 | } 25 | int f = 3, limit = sqrt(x)+1; 26 | while (f < limit){ 27 | if (x%f == 0){ 28 | 29 | x /= f; 30 | factor[l++] = f; 31 | } 32 | else { 33 | f += 2; 34 | limit = sqrt(x)+1; 35 | } 36 | } 37 | if (x > 1) factor[l++] = x; 38 | } 39 | 40 | int main(){ 41 | int A[10000]; 42 | int l; 43 | for (int i=1; i<=10000; ++i){ 44 | prime_factorization(i, A, l); 45 | printf(" ******** %d ******** \n",i); 46 | for (int j=0; j= STACKSIZE) 26 | printf("WARNING: stack overflow push x=%d\n",x); 27 | else{ 28 | s.s[++s.last]=x; 29 | s.count++;} 30 | } 31 | 32 | int pop(){ 33 | int x; 34 | if (s.count <= 0) 35 | printf("Warning: empty stack pop\n"); 36 | else{ 37 | x=s.s[s.last]; 38 | s.last--; 39 | s.count--;} 40 | return(x); 41 | } 42 | 43 | int empty(){ 44 | if (s.count<=0) return(1); 45 | else return(0); 46 | } 47 | 48 | 49 | int main(){ 50 | init_stack(); 51 | printf("insert numbers, stop with -1\n"); 52 | int m; 53 | do{ 54 | scanf("%d",&m); 55 | push(m); 56 | }while (m!=-1); 57 | printf("number of items: %d\n",s.count); 58 | printf("insert number of items to pop and print: "); 59 | scanf("%d",&m); 60 | int i; 61 | for (i=0; i 19 | #include 20 | #include 21 | #include 22 | #define MAX 10000 23 | using namespace std; 24 | 25 | char P[MAX],T[MAX]; 26 | int m,n,b[MAX+1]; 27 | 28 | void kmpPreprocess(){ 29 | int j=0; 30 | b[0]=-1; 31 | b[1]=0; 32 | for (int i=1; i=0 and P[i]!=P[j]) j=b[j]; 34 | j++; 35 | b[i+1]=j; 36 | } 37 | } 38 | 39 | void kmpSearch(){ 40 | int j=0; 41 | for (int i=0; i=0 and T[i]!=P[j]) j=b[j]; 43 | j++; 44 | if (j==m){ 45 | printf("%d\n",i+1-j); 46 | j=b[j]; 47 | } 48 | } 49 | } 50 | 51 | int main(){ 52 | scanf("%s %s",&T,&P); 53 | m=strlen(P); 54 | n=strlen(T); 55 | kmpPreprocess(); 56 | kmpSearch(); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /algebra/prime_generator/prime_generator.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Prime number generator using Sieve of Erastosthenes. 3 | 4 | Sieve of Erastosthenes: go from i=2 to sqrt(n) and for each i mark the 5 | multiples of i in a bool array of size n as visited, the unvisited spots are 6 | prime numbers (exception: numbers 0 and 1). 7 | 8 | Computing all primes <= n takes O(n). 9 | 10 | Can be further optimized by 11 | * using char instead bool array saving 256 values 12 | * using modular arithmetic 13 | 14 | (c) 2015 Josef Ziegler 15 | 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include "string.h" 22 | #define N (1<<20) 23 | #define SQRTN (1<<10) 24 | using namespace std; 25 | 26 | bool B[N+1]; // mark as visited 27 | int P[N+1]; // P[i] the ith largest prime number, domain: 0,...,pcnt-1 28 | int pcnt; 29 | int n; 30 | 31 | void sieve(){ 32 | B[0]=true; 33 | B[1]=true; 34 | pcnt=0; 35 | int sqrtn=sqrt(n)+1; 36 | for (int i=2; i<=sqrtn; i++) 37 | if (!B[i]){ 38 | P[pcnt++]=i; 39 | for (int j=2; (j*i)<=n; j++) B[j*i]=true; 40 | } 41 | for (int i=sqrtn+1; i<=n; i++) 42 | if (!B[i]) 43 | P[pcnt++]=i; 44 | } 45 | 46 | int main(){ 47 | memset(B,0,sizeof B); 48 | scanf("%d",&n); 49 | if (n>N) return -1; 50 | sieve(); 51 | for (int i=0; i 12 | #include 13 | #include 14 | #define MAX 100000 15 | using namespace std; 16 | 17 | int n; /* number of items (integers) to sort */ 18 | int C[MAX]; 19 | 20 | /* function to determine the partitions */ 21 | /* partitions the array and returns the middle subscript */ 22 | int partition(int A[], int top, int bottom){ 23 | int x=A[top]; /* pivot element = first element */ 24 | int i=top; 25 | int j=bottom; 26 | int tmp; 27 | do { 28 | while (x>A[j]) j--; 29 | while (x PII; 20 | 21 | void initialize(int node, int b, int e, int M[MAXIND], int A[MAXN], int N){ 22 | if (b==e) M[node]=b; 23 | else { 24 | initialize(2*node, b, (b+e)/2, M, A, N); 25 | initialize(2*node+1,(b+e)/2+1,e,M, A, N); 26 | if (A[M[2*node]]<=A[M[2*node+1]]) M[node]=M[2*node]; 27 | else M[node]=M[2*node+1]; 28 | } 29 | } 30 | 31 | // find minimum value in some interval [i,j] 32 | int query(int node, int b, int e, int M[MAXIND], int A[MAXN], int i, int j){ 33 | int p1,p2; 34 | if (i>e || j=i && e<=j) return M[node]; 36 | p1=query(2*node ,b,(b+e)/2, M,A,i,j); 37 | p2=query(2*node+1,(b+e)/2+1,e,M,A,i,j); 38 | if (p1==-1) return M[node]=p2; 39 | if (p2==-1) return M[node]=p1; 40 | if (A[p1]<=A[p2]) return M[node]=p1; 41 | return M[node]=p2; 42 | } 43 | 44 | int main(){ 45 | // call both functions with node=1, b=0, e=N-1 46 | ; 47 | } 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /dynamic_programming/LIS/LIS_quadratic.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Longest (strictly) Increasing Subsequence (LIS), O(n^2). 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define COMMENT 0 13 | using namespace std; 14 | 15 | int N,A[10001]; /* length of the sequence and sequence */ 16 | int DP[10001]; 17 | int pre[10001]; 18 | 19 | int main(){ 20 | scanf("%d",&N); 21 | for (int i=0; i=DP[i]){ 32 | DP[i]=DP[j]+1; 33 | pre[i]=j;} 34 | 35 | int best=0; 36 | for (int i=0; i S; 52 | do { 53 | S.push(at); 54 | at=pre[at]; 55 | } while (at!=-1); 56 | 57 | while (!S.empty()) { 58 | printf("%d ",A[S.top()]); 59 | S.pop();} 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /dynamic_programming/LCS/lcs_length_iterative.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Longest Common Subsequence Length (LCS), (iterative). 3 | 4 | Bottom up, iterative, very efficient, O(n^2). 5 | This is iterative (because it uses nested loops instead of recursion) or 6 | bottom up (because the order we fill in the array is from smaller simpler 7 | subproblems to bigger more complicated ones). 8 | 9 | (c) 2015 Josef Ziegler 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "string.h" 17 | using namespace std; 18 | 19 | char A[1000]; 20 | char B[1000]; 21 | int L[1000][1000]; 22 | int i,j,m,n; 23 | 24 | int lcs_length(char * A, char * B) 25 | { 26 | m=strlen(A); 27 | n=strlen(B); 28 | /* allocate storage for array L; */ 29 | for (i = m; i >= 0; i--) 30 | for (j = n; j >= 0; j--) 31 | { 32 | if (A[i] == '\0' || B[j] == '\0') L[i][j] = 0; 33 | else if (A[i] == B[j]) L[i][j] = 1 + L[i+1][j+1]; 34 | else L[i][j] = max(L[i+1][j], L[i][j+1]); 35 | } 36 | return L[0][0]; 37 | } 38 | 39 | int main(){ 40 | memset(L,-1,sizeof L); 41 | scanf("%s %s",A,B); 42 | printf("solution:%d\n\n",lcs_length(A,B)); 43 | m=strlen(A); 44 | n=strlen(B); 45 | printf("%3c",' '); 46 | for (i = 0; i <= m; i++) printf("%3c",A[i]); 47 | printf("\n"); 48 | for (i = 0; i <= n; i++){ 49 | printf("%3c",B[i]); 50 | for (j = 0; j <= m; j++) 51 | printf("%3d",L[j][i]); 52 | printf("\n"); 53 | } 54 | 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /combinatorics/all_subset/all_subset_int.cc: -------------------------------------------------------------------------------- 1 | /* 2 | All subset (int). 3 | 4 | Constructing all subsets of 1, 2, ..., n via backtracking. 5 | This file was meant to be extensible. 6 | Adapted parts from the book "Programming Challenges" by Steven S. Skiena 7 | and Miguel A. Revilla, 2003, Springer. 8 | 9 | (c) 2015 Josef Ziegler 10 | 11 | */ 12 | 13 | #include 14 | #define MAXCANDIDATES 10000 15 | using namespace std; 16 | 17 | bool finished = false; /* found all solutions yet? */ 18 | 19 | bool is_a_solution(int A[], int k, int n){ 20 | return (k==n); 21 | } 22 | 23 | void construct_candidates(int A[], int k, int n, int C[], int *ncandidates){ 24 | C[0]=0; 25 | C[1]=1; 26 | *ncandidates = 2;} 27 | 28 | void process_solution(int A[], int k, int n){ 29 | printf("{"); 30 | for (int i=1; i<=k; i++){ 31 | if (A[i]==1) printf(" %d",i);} 32 | printf(" }\n"); 33 | } 34 | 35 | 36 | void backtrack(int A[], int k, int n){ // input - any data type possible 37 | int C[MAXCANDIDATES]; /* candidates for next position */ 38 | int ncandidates; /* next position candidate count */ 39 | if (is_a_solution(A,k,n)) 40 | process_solution(A,k,n); 41 | else { 42 | k++; 43 | construct_candidates(A,k,n,C,&ncandidates); 44 | for (int i=0; i=QUEUESIZE){ 27 | printf("Warning: queue overflow enqueue x=%d\n",x);} 28 | else { 29 | q.last=(q.last+1)%QUEUESIZE; 30 | q.q[q.last]=x; 31 | q.count++;} 32 | } 33 | 34 | int dequeue(){ 35 | int x; 36 | if (q.count <= 0){ 37 | printf("Warning: empty queue dequeue\n");} 38 | else { 39 | x=q.q[q.first]; 40 | q.first=(q.first+1)%QUEUESIZE; 41 | q.count--;} 42 | return(x); 43 | } 44 | 45 | int empty(){ 46 | if (q.count <= 0) return(1); 47 | else return(0); 48 | } 49 | 50 | int main(){ 51 | printf("stop by inserting -1 at the end\n"); 52 | printf("insert:\n"); 53 | init_queue(); 54 | int m; 55 | do{ 56 | scanf("%d",&m); 57 | enqueue(m); 58 | }while(m!=-1); 59 | printf("number of elements (including -1): %d\n",q.count); 60 | printf("first and last element: %d, %d\n",q.q[q.first], q.q[q.last]); 61 | printf("remove and print number of elements:"); 62 | int x,i; 63 | scanf("%d",&x); 64 | for (i=0;i 9 | #include 10 | using namespace std; 11 | 12 | #define MAXV 100 /* maximum number of vertices */ 13 | #define MAXDEGREE 50 /* maximum vertex outdegree */ 14 | 15 | typedef struct { 16 | int edges[MAXV+1][MAXDEGREE]; /* adjacency info */ 17 | int degree[MAXV+1]; /* outdegree of each vertex */ 18 | int nvertices; /* number of vertices in graph */ 19 | int nedges; /* number of edges in graph */ 20 | } graph; 21 | 22 | void initialize(graph *g){ 23 | g->nvertices = 0; 24 | g->nedges = 0; 25 | memset(g->degree,0,MAXV+1);} 26 | 27 | void insert_edge(graph *g, int x, int y, bool directed){ 28 | g->edges[x][g->degree[x]++] = y; 29 | if (!directed) insert_edge(g,y,x,true); 30 | else g->nedges++;} 31 | 32 | void read(graph *g, bool directed){ 33 | int m; /* number of edges */ 34 | int x,y; /* vertices in edge (x,y) */ 35 | initialize(g); 36 | scanf("%d %d",&(g->nvertices),&m); 37 | for (int i=1; i<=m; i++){ 38 | scanf("%d %d",&x,&y); 39 | insert_edge(g,x,y,directed);} 40 | } 41 | 42 | void print(graph *g){ 43 | for (int i=1; i<=g->nvertices; i++){ 44 | printf("%d: ",i); 45 | for (int j=0; jdegree[i]; j++){ 46 | printf(" %d",g->edges[i][j]);} 47 | putchar(10); 48 | } 49 | } 50 | 51 | int main(){ 52 | graph g; 53 | read(&g,true); 54 | print(&g); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /data_structure/heap/heap.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Heap. 3 | 4 | This program implements a min-heap. 5 | Implemented using an array, tree structure is guaranteed to be balanced. 6 | 7 | get_min: O(1) 8 | insert value: O(log n) 9 | delete_min: O(log n) 10 | 11 | Parent has key larger equal his two children. 12 | 13 | 1 14 | 2 3 15 | 4 5 6 7 16 | 8 9 10 17 | 18 | Current node: n. 19 | Left child: 2*n. 20 | Right child: 2*n+1. 21 | 22 | (c) 2015 Josef Ziegler 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | using namespace std; 31 | 32 | vector V; 33 | 34 | int get_min(vector& A){ 35 | if (A.size() <= 1) return -1; // there is no min 36 | return A[1]; 37 | } 38 | 39 | void delete_min(vector& A){ 40 | A[1]=A[A.size()-1]; 41 | int index=1; 42 | // replace root with node with last index, now "bubble down" 43 | while (1){ 44 | int left=index*2, right=index*2+1; 45 | if (left < A.size()){ 46 | if (right < A.size()){ 47 | if (A[right] < A[left]) { // there is a left and right node 48 | swap(A[right], A[index]); 49 | index = rght; 50 | continue; 51 | } 52 | } 53 | swap(A[left], A[index]); // there is only a left node or the left node is smaller 54 | index = left; 55 | } 56 | break; // index == A.size()-1 57 | } 58 | } 59 | 60 | void insert(vector& A, int x){ 61 | A.push_back(x); 62 | int index = A.size()-1; 63 | 64 | 65 | int main(){ 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /combinatorics/all_permutation/all_permutation_int.cc: -------------------------------------------------------------------------------- 1 | /* 2 | All permutation (int). 3 | 4 | Constructs all permutations of 1, 2, ..., n via backtracking. 5 | This file was meant to be extensible. 6 | Adapted parts from the book "Programming Challenges" by Steven S. Skiena 7 | and Miguel A. Revilla, 2003, Springer. 8 | 9 | (c) 2015 Josef Ziegler 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | #define MAXCANDIDATES 10000 16 | #define MAXN 10000 17 | using namespace std; 18 | 19 | bool is_solution(int A[], int k, int n){ 20 | return(k==n); 21 | } 22 | 23 | void process_solution(int A[], int k, int n){ 24 | for(int i=1; i<=k; i++) printf(" %d",A[i]); 25 | printf("\n"); 26 | } 27 | 28 | void construct_candidates(int A[], int k, int n, int C[], int *ncandidates){ 29 | bool in_perm[MAXN]; 30 | memset(in_perm,0,MAXN); 31 | for (int i=1; i 13 | #include 14 | #include "string.h" 15 | #define MAX 1025 16 | using namespace std; 17 | 18 | int tree[MAX][MAX],t,n,a,b,c,d; 19 | int F[MAX][MAX]; 20 | 21 | void update(int x, int y, int val){ 22 | x++; 23 | y++; 24 | while (x <= MAX){ 25 | int y1=y; 26 | while (y1 <= MAX){ 27 | tree[x][y1]+=val; 28 | y1+=y1&-y1;} 29 | x+=x&-x;} 30 | } 31 | 32 | int read(int x, int y){ 33 | x++; 34 | y++; 35 | int sum=0; 36 | while (x>=1){ 37 | int y1=y; 38 | while (y1>=1){ 39 | sum+=tree[x][y1]; 40 | y1-=y1&-y1;} 41 | x-=x&-x;} 42 | return sum; 43 | } 44 | 45 | char S[4]; 46 | 47 | int main(){ 48 | scanf("%d",&t); 49 | while (t--){ 50 | memset(tree,0,sizeof tree); 51 | memset(F,0,sizeof F); 52 | scanf("%d",&n); 53 | while (1){ 54 | scanf("%s",&S); 55 | if (S[0]=='E') break; 56 | if (S[2]=='T'){ 57 | scanf("%d %d %d",&a,&b,&c); 58 | update(a,b,c-F[a][b]); 59 | F[a][b]=c; 60 | } 61 | else{ 62 | scanf("%d %d %d %d",&a,&b,&c,&d); 63 | printf("%d\n",read(c,d)+read(a-1,b-1)-read(a-1,d)-read(c,b-1)); 64 | } 65 | } 66 | printf("\n"); 67 | } 68 | return 0; 69 | } 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /graph_theory/prim/prim_O(nlogn).cc: -------------------------------------------------------------------------------- 1 | /* 2 | Prim's Algorithm (Minimum Spanning Tree) O(n log n). 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #define MAXV 1001 12 | #define MAXINT 1000000000 13 | using namespace std; 14 | 15 | int dist[MAXV]; 16 | int parent[MAXV]; 17 | int n,m; 18 | list > weight[MAXV]; // adjacency list 19 | list > :: iterator iter; 20 | class pqnode{ 21 | public: 22 | int n; 23 | pqnode(int x=0){n=x;} 24 | bool operator<(const struct pqnode &p2) const{ 25 | return dist[n] > dist[p2.n];} 26 | }; 27 | 28 | void prim(int s){ 29 | int y,W; 30 | int intree[MAXV]; 31 | for (int i=1; i<=n; i++){ 32 | dist[i]=MAXINT; 33 | parent[i]=-1; 34 | intree[i]=false; 35 | } 36 | dist[s]=0; 37 | priority_queue P; 38 | P.push(pqnode(s)); 39 | while (P.empty()==false){ 40 | int v=P.top().n; 41 | P.pop(); 42 | intree[v]=true; 43 | for (iter=weight[v].begin(); iter!=weight[v].end(); iter++){ 44 | y=iter->first; 45 | W=iter->second; 46 | if ((dist[y]>W) && (intree[y]==false)){ 47 | parent[y]=v; 48 | dist[y]=W; 49 | P.push(pqnode(y));} 50 | } 51 | } 52 | } 53 | 54 | int main(){ 55 | scanf("%d %d",&n,&m); 56 | for (int i=1; i<=m; i++){ 57 | int a,b,c; 58 | scanf("%d %d %d",&a,&b,&c); 59 | weight[a].push_back(make_pair (b,c)); 60 | weight[b].push_back(make_pair (a,c)); 61 | } 62 | prim(1); 63 | for (int i=1; i<=n; i++){ 64 | printf("%d %d\n",i,parent[i]); 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /combinatorics/next_permutation/next_permutation.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Next permutation. 3 | 4 | Next permutation computes the next lexicographical permutation 5 | of a given array of integers. 6 | 7 | The main function computes the next permutation until there is no more next 8 | permutation, i.e. the given integer sequence is sorted in decreasing order 9 | (also known as snail sort). 10 | 11 | (c) 2015 Josef Ziegler 12 | 13 | */ 14 | 15 | #include 16 | #include 17 | #define INF 1000000000 18 | using namespace std; 19 | 20 | // returns false if there were was no next permutation 21 | // else returns true 22 | bool next_permutation(int* A, int n) { 23 | int at=-1; 24 | for (int i=n-2; i>=0; i--){ 25 | if (A[i]A[at]) { 33 | f=A[i]; 34 | fidx=i;}} 35 | 36 | int ins=A[at]; 37 | A[at]=f; 38 | A[fidx]=ins; 39 | 40 | // this is essential since the integers in the interval [at+1,l-1] are 41 | // sorted in descending order, but need to be sorted in ascending order 42 | int diff=n-(at+1); 43 | for (int i=0; i 11 | #include 12 | #include 13 | #include 14 | #define COMMENT 0 15 | using namespace std; 16 | 17 | int N,X[10001],M[10001],P[10001],L; 18 | 19 | int main(){ 20 | scanf("%d",&N); 21 | for (int i=0; i=down){ 40 | mid=(up+down)/2; 41 | if (X[M[mid]]X[i]){ 46 | M[j+1]=i; 47 | L=max(L,j+1);} 48 | } 49 | 50 | #if COMMENT 51 | for (int i=0; i S; 59 | int at=M[L]; 60 | while (at!=-1){ 61 | S.push(at); 62 | at=P[at];} 63 | while (!S.empty()){ 64 | printf("%d ",X[S.top()]); 65 | S.pop();} 66 | printf("\n"); 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /graph_theory/dijkstra/dijkstra_O(nlogn)_vector_nopqclass.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Dijkstra's Algorithm O(n log n) using STL vector. 3 | 4 | Computes the one-source shortest path in weighted graphs in O(n log n) 5 | using STL vector and a pq struct used for the priority queue. 6 | 7 | (c) 2015 Josef Ziegler 8 | 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #define MAXV 10000 15 | #define INF 2000000 16 | using namespace std; 17 | 18 | int dist[MAXV]; 19 | int parent[MAXV]; 20 | int n,m; 21 | vector > weight[MAXV]; // adjacency list; weight(a) contains (b,w) 22 | // means edge from a to b with weight w 23 | vector >:: iterator iter; 24 | 25 | struct pq{ 26 | bool operator()(int a, int b){ 27 | return dist[a]>dist[b]; 28 | } 29 | }; 30 | 31 | void dijkstra(int s){ 32 | int y,W; 33 | priority_queue, pq> P; 34 | for (int i=1; i<=n; i++){ 35 | dist[i] = INF; 36 | parent[i] = -1;} 37 | 38 | dist[s]=0; 39 | P.push(s); 40 | while (P.empty()==false){ 41 | int k=P.top(); 42 | P.pop(); 43 | for (iter = weight[k].begin(); iter!=weight[k].end(); iter++){ 44 | y = iter->first; 45 | W = iter->second; 46 | if (dist[y] > dist[k]+W){ 47 | dist[y]=dist[k]+W; 48 | parent[y]=k; 49 | P.push(y); 50 | } 51 | } 52 | } 53 | } 54 | 55 | int main(){ 56 | scanf("%d %d",&n,&m); 57 | for (int i=1; i<=m; i++){ 58 | int a,b,c; 59 | scanf("%d %d %d",&a,&b,&c); 60 | weight[a].push_back(make_pair (b,c)); // directed 61 | } 62 | dijkstra(1); 63 | for (int i=1; i<=n; i++){ 64 | printf("%d: %d\n",i,dist[i]); 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /graph_theory/ford_fulkerson/ford_fulkerson_capacity_scaling.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Ford Fulkerson's Algorithm with Capacity Scaling (Maxflow/Mincut). 3 | 4 | The run-time complexity is O(E^2 log C), C = maxflow. 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | // #define NDEBUG 24 | #include "assert.h" 25 | #include "string.h" 26 | #define MP make_pair 27 | #define COMMENT 1 28 | #define MAXV 100 29 | using namespace std; 30 | 31 | typedef unsigned uint; 32 | typedef long long int llint; 33 | typedef pair PII; 34 | 35 | 36 | int M,N,C[MAXV][MAXV]; // #edges, #vertices, capacity matrix 37 | bool B[MAXV]; 38 | int s,t; // source, sink 39 | int w; // used for capacity scaling 40 | 41 | bool inc(int x){ 42 | if (x==t) return true; 43 | B[x]=true; 44 | for (int y=0; y<=N; y++){ 45 | if (C[x][y]>=w and !B[y] and inc(y)){ 46 | C[x][y]-=w; 47 | C[y][x]+=w; 48 | return true; 49 | } 50 | } 51 | return false; 52 | } 53 | 54 | 55 | int main(){ 56 | scanf("%d %d",&N,&M); 57 | scanf("%d %d",&s,&t); 58 | memset(C,0,sizeof C); 59 | int maxc=0; 60 | for (int i=0; i0){ 70 | memset(B,0,sizeof B); 71 | if (inc(s)) sol+=w; 72 | else w/=2; 73 | } 74 | printf("%d\n",sol); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /sorting/mergesort/mergesort.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Mergesort. 3 | 4 | O(n log n). 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #define MAX 100000 14 | using namespace std; 15 | 16 | void merge(int *A, int *tmp, int top, int mid, int bottom); 17 | void m_sort(int *A, int *tmp, int top, int bottom); 18 | 19 | void mergesort(int *A, int *tmp, int array_size){ 20 | m_sort(A,tmp,0,array_size-1); 21 | } 22 | 23 | 24 | void m_sort(int *A, int *tmp, int lo, int hi){ 25 | /* using closed intervals */ 26 | if (lo 12 | #include 13 | #include 14 | #define MAXV 10000 15 | #define INF 2000000 16 | using namespace std; 17 | 18 | int dist[MAXV]; 19 | int parent[MAXV]; 20 | int n,m; 21 | list > weight[MAXV]; // adjacency list; weight(a) contains (b,w) 22 | // means edge from a to b with weight w 23 | list >:: iterator iter; 24 | 25 | class pqnode{ 26 | public: 27 | int n; 28 | pqnode (int x=0) { 29 | n = x;} 30 | bool operator<(const struct pqnode p2) const{ 31 | return dist[n] > dist[p2.n];} 32 | }; 33 | 34 | void dijkstra(int s){ 35 | int y,W; 36 | priority_queue P; 37 | for (int i=1; i<=n; i++){ 38 | dist[i] = INF; 39 | parent[i] = -1;} 40 | 41 | dist[s]=0; 42 | P.push(pqnode(s)); 43 | while (P.empty()==false){ 44 | int k=P.top().n; 45 | P.pop(); 46 | for (iter = weight[k].begin(); iter!=weight[k].end(); iter++){ 47 | y = iter->first; 48 | W = iter->second; 49 | if (dist[y] > dist[k]+W){ 50 | dist[y]=dist[k]+W; 51 | parent[y]=k; 52 | P.push(pqnode(y)); 53 | } 54 | } 55 | } 56 | } 57 | 58 | int main(){ 59 | scanf("%d %d",&n,&m); 60 | for (int i=1; i<=m; i++){ 61 | int a,b,c; 62 | scanf("%d %d %d",&a,&b,&c); 63 | weight[a].push_back(make_pair (b,c)); // directed 64 | } 65 | dijkstra(1); 66 | for (int i=1; i<=n; i++){ 67 | printf("%d: %d\n",i,dist[i]); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /graph_theory/dijkstra/dijkstra_O(nlogn)_vector.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Dijkstra's Algorithm O(n log n) using STL vector. 3 | 4 | Computes the one-source shortest path in weighted graphs in O(n log n) 5 | using STL vector and a pqnode class used for the priority queue. 6 | 7 | (c) 2015 Josef Ziegler 8 | 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #define MAXV 10000 15 | #define INF 2000000 16 | using namespace std; 17 | 18 | int dist[MAXV]; 19 | int parent[MAXV]; 20 | int n,m; 21 | vector > weight[MAXV]; // adjacency list; weight(a) contains (b,w) 22 | // means edge from a to b with weight w 23 | vector >:: iterator iter; 24 | 25 | class pqnode{ 26 | public: 27 | int n; 28 | pqnode (int x=0) { 29 | n = x;} 30 | bool operator<(const struct pqnode p2) const{ 31 | return dist[n] > dist[p2.n];} 32 | }; 33 | 34 | void dijkstra(int s){ 35 | int y, W; 36 | priority_queue P; 37 | for (int i=1; i<=n; i++){ 38 | dist[i] = INF; 39 | parent[i] = -1;} 40 | 41 | dist[s]=0; 42 | P.push(pqnode(s)); 43 | while (P.empty()==false){ 44 | int k=P.top().n; 45 | P.pop(); 46 | for (iter = weight[k].begin(); iter!=weight[k].end(); iter++){ 47 | y = iter->first; 48 | W = iter->second; 49 | if (dist[y] > dist[k]+W){ 50 | dist[y]=dist[k]+W; 51 | parent[y]=k; 52 | P.push(pqnode(y)); 53 | } 54 | } 55 | } 56 | } 57 | 58 | int main(){ 59 | scanf("%d %d",&n,&m); 60 | for (int i=1; i<=m; i++){ 61 | int a,b,c; 62 | scanf("%d %d %d",&a,&b,&c); 63 | weight[a].push_back(make_pair (b,c)); // directed 64 | } 65 | dijkstra(1); 66 | for (int i=1; i<=n; i++){ 67 | printf("%d: %d\n",i,dist[i]); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /graph_theory/toposort/toposort.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Topological Sorting on DAGs. 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #define MAXV 100 + 1 12 | #define MAXDEGREE 100 13 | using namespace std; 14 | 15 | int nedges, nvertices; /* number of edges and number of vertices in graph */ 16 | int edges[MAXV][MAXDEGREE]; /* adjacency info */ 17 | int degree[MAXV]; /* outdegree of each vertex */ 18 | int parent[MAXV]; /* discovery relation */ 19 | bool discovered[MAXV]; /* which vertices have been found */ 20 | bool processed[MAXV]; /* which vertices have been processed */ 21 | int A[MAXV]; 22 | 23 | void compute_indegrees(int in[]){ 24 | memset(in,0,sizeof A); 25 | for (int i=1; i<=nvertices; i++) 26 | for (int j=0; j Q; /* vertices of indegree 0 */ 33 | int x,y; /* current and next vertex */ 34 | compute_indegrees(indegree); 35 | for (int i=1; i<=nvertices; i++) 36 | if (indegree[i]==0) Q.push(i); 37 | int j=0; 38 | while (Q.empty()==false){ 39 | j++; 40 | x=Q.front(); 41 | Q.pop(); 42 | sorted[j]=x; 43 | for (int i=0; i 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | struct strCmp{ 14 | bool operator()(char* s1, char* s2){ 15 | return(strcmp(s1,s2)<0);} 16 | }; 17 | 18 | map M; 19 | map ::iterator iter; 20 | char S[10000]; 21 | char SS[10000][10000]; 22 | int v; 23 | 24 | int main(){ 25 | M.clear(); /* not really necessary though */ 26 | printf("insert your strings with the according values -> string - value - newline\n"); 27 | printf("stop by inserting 'STOP' and any value\n"); 28 | int i=0; 29 | do{ 30 | scanf("%s",SS[i]); 31 | scanf("%d",&v); 32 | M.insert(make_pair(SS[i],v)); 33 | i++; 34 | } while (strcmp(SS[i-1],"STOP")!=0); 35 | printf("'y' empty(), 'p' print all pairs, 's' size(), 'f' find(), 'c' clear and 'e' erase()\n"); 36 | printf(" type q to quit\n"); 37 | char c; 38 | while (1){ 39 | c=getchar(); 40 | if (c=='y'){ 41 | if (M.empty()) 42 | printf("empty\n"); 43 | else 44 | printf("not empty\n");} 45 | else if (c=='p'){ 46 | for (iter=M.begin(); iter!=M.end(); iter++) 47 | printf("%s %d\n",iter->first,iter->second);} 48 | else if (c=='s'){ 49 | printf("%d\n",M.size());} 50 | else if (c=='f'){ 51 | printf("what do you want to look for?\n"); 52 | scanf("%s",S); 53 | iter=M.find(S); 54 | if (iter==M.end()) 55 | printf("Not found\n"); 56 | else printf("found:\n%s %d\n",(*iter).first,iter->second); 57 | } 58 | else if(c=='c'){ 59 | M.clear();} 60 | else if(c=='e'){ 61 | printf("what do you want to erase?\n"); 62 | scanf("%s",S); 63 | iter=M.find(S); 64 | if (iter==M.end()) 65 | printf("Not found\n"); 66 | else{ M.erase(iter); 67 | printf("erased\n");} 68 | } 69 | else if(c=='q'){ 70 | break;} 71 | } 72 | } 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /dynamic_programming/MCM/matrix_chain_multiplication.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Matrix Chain Multiplication. 3 | 4 | Output the minimum number of multiplications needed. 5 | 6 | Input 7 | N (# Matrices) 8 | N lines with two integers a, b 9 | the dimensions of the matrices (a x b) that need to be multiplied in 10 | the given order 11 | 12 | (c) 2015 Josef Ziegler 13 | 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #define INF 1000000000 21 | #define COMMENT 0 22 | using namespace std; 23 | 24 | int N; 25 | int P[101]; 26 | int DP[101][101]; 27 | int S[101][101]; /* for extracting the actual sequence */ 28 | 29 | void recovery(int a, int b){ 30 | if (a-b==0) printf("A%d",a+1); 31 | else { 32 | printf("("); 33 | recovery(a,S[a][b]); 34 | printf(" x "); 35 | recovery(S[a][b]+1,b); 36 | printf(")"); 37 | } 38 | } 39 | 40 | int main(){ 41 | scanf("%d",&N); 42 | for (int i=0; i 9 | #include 10 | #define MAXV 101 11 | #define MAXDEGREE 101 12 | #define MAXINT 2000000000 13 | using namespace std; 14 | 15 | int edges[MAXV][MAXDEGREE]; /* adjacency info */ 16 | int degree[MAXV]; /* outdegree of each vertex */ 17 | int parents[MAXV]; /* discovery relation */ 18 | int weight[MAXV][MAXDEGREE]; /* edge weight */ 19 | int nvertices, nedegs; /* number of vertices and edges of graph */ 20 | 21 | void read(){ 22 | int x,y,m,c; 23 | memset(degree,0,sizeof degree); 24 | scanf("%d %d",&nvertices,&m); 25 | for (int i=0; i Weight) && (intree[w]==false)){ 52 | distance[w]=Weight; 53 | parents[w]=v;} 54 | } 55 | v=1; 56 | dist=MAXINT; 57 | for (int i=1; i<=nvertices; i++){ 58 | if ((intree[i]==false) && (dist > distance[i])){ 59 | dist = distance[i]; 60 | v=i;} 61 | } 62 | } 63 | } 64 | 65 | int main(){ 66 | read(); 67 | prim(1); 68 | printf("parents: \n"); 69 | for (int i=1; i<=nvertices; i++) 70 | printf("%d: %d\n",i,parents[i]); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /graph_theory/dfs/dfs_vector.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Depth-First Search, Graph Traversal (using STL vectors) 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #define MAXV 1000 12 | using namespace std; 13 | 14 | vector edges[MAXV]; /* adjacency info */ 15 | int parent[MAXV]; /* discovery relation */ 16 | bool discovered[MAXV]; /* which vertices have been found */ 17 | bool processed[MAXV]; /* which vertices have been processed */ 18 | int nvertices,nedges; 19 | bool finished; 20 | 21 | void init(){ 22 | memset(processed,0,sizeof processed); 23 | memset(discovered,0,sizeof discovered); 24 | memset(parent,-1,sizeof parent); 25 | for (int i=0; i::iterator it=edges[v].begin(); it!=edges[v].end(); ++it){ 66 | int y=*it; /* successor vertex */ 67 | if (discovered[y]==false){ 68 | parent[y]=v; 69 | dfs(y); 70 | } else if (processed[y]==false){ 71 | process_edge(v,y); 72 | } 73 | if (finished) return; 74 | } 75 | processed[v]=true; 76 | } 77 | 78 | 79 | int main(){ 80 | /* undirected */ 81 | read(); 82 | dfs(1); 83 | } 84 | -------------------------------------------------------------------------------- /graph_theory/dfs/dfs.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Depth-First Search, Graph Traversal. 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #define MAXV 1000+1 11 | #define MAXDEGREE 1000 12 | 13 | int edges[MAXV][MAXDEGREE]; /* adjacency info */ 14 | int degree[MAXV]; /* outdegree of each vertex */ 15 | int parent[MAXV]; /* discovery relation */ 16 | bool discovered[MAXV]; /* which vertices have been found */ 17 | bool processed[MAXV]; /* which vertices have been processed */ 18 | int nvertices,nedges; 19 | bool finished=false; 20 | 21 | void init(){ 22 | memset(processed,0,sizeof processed); 23 | memset(discovered,0,sizeof discovered); 24 | memset(parent,-1,sizeof parent); 25 | memset(degree,0,sizeof degree); 26 | } 27 | 28 | void process_vertex(int v){ 29 | printf("processed vertex %d\n",v); 30 | } 31 | 32 | void find_path(int start, int end){ 33 | if ((start==end) || (end==-1)) 34 | printf("\n%d",start); 35 | else{ 36 | find_path(start,parent[end]); 37 | printf(" %d",end);} 38 | } 39 | 40 | void process_edge(int x,int y){ 41 | if (parent[x]!=y){ /* found back edge */ 42 | printf("Cycle from %d to %d\n",y,x); 43 | find_path(y,x); 44 | finished=true;} 45 | } 46 | bool valid_edge(int v){ 47 | return true;} 48 | 49 | 50 | void read(){ 51 | int m,x,y; 52 | init(); 53 | nedges=nvertices=0; 54 | scanf("%d %d",&nvertices,&m); 55 | for (int i=1; i<=m; i++){ 56 | scanf("%d %d",&x,&y); 57 | edges[x][degree[x]++]=y; 58 | edges[y][degree[y]++]=x; 59 | } 60 | } 61 | 62 | 63 | void dfs(int v){ 64 | int y; /* successor vertex */ 65 | discovered[v]=true; 66 | process_vertex(v); 67 | if (finished) return; 68 | for (int i=0; i 12 | #include 13 | #include 14 | #include 15 | #define EPSILON (1e-7) 16 | using namespace std; 17 | 18 | typedef struct { 19 | double x; 20 | double y; 21 | } point; 22 | 23 | typedef struct { 24 | double a; /* x-coefficient */ 25 | double b; /* y-coefficient */ 26 | double c; /* constant term */ 27 | } line; 28 | 29 | void points_to_line(point p1, point p2, line *l){ 30 | if (p1.x == p2.x){ /* degeneracy */ 31 | l->a = 1; 32 | l->b = 0; 33 | l->c = -p1.x; 34 | } else { 35 | l->a = -(p1.y - p2.y) / (p1.x - p2.x); 36 | l->b = 1; 37 | l->c = -(l->a * p1.x) - (l->b * p1.y); 38 | } 39 | } 40 | 41 | void point_and_slope_to_line(point p, double m, line *l){ 42 | l->a = -m; 43 | l->b = 1; 44 | l->c = -((l->a * p.x) + (l->b * p.y)); 45 | } 46 | 47 | bool parallelQ(line l1, line l2){ 48 | return ((abs(l1.a - l2.a) <= EPSILON) && (abs(l1.b - l2.b) <= EPSILON));} 49 | 50 | bool same_lineQ(line l1, line l2){ 51 | return (parallelQ(l1,l2) && (abs(l1.c - l2.c) <= EPSILON));} 52 | 53 | void intersection_point(line l1, line l2, point *p){ 54 | if (same_lineQ(l1,l2)){ 55 | p->x = 0.0; 56 | p->y = 0.0; 57 | return;} 58 | if (parallelQ(l1,l2)) return; 59 | p->x = (l2.b * l1.c - l1.b * l2.c) / (l1.b * l2.a - l2.b * l1.a); 60 | if (abs(l1.b) > EPSILON) /* test for vertical line */ 61 | p->y = - (l1.a * (p->x) + l1.c); 62 | else 63 | p->y = - (l2.a * (p->x) + l2.c);} 64 | 65 | double angle(line l1, line l2){ /* in radiants */ 66 | if (parallelQ(l1,l2)) return 0.0; 67 | return atan((l1.a * l2.b - l2.a * l1.b)/(l1.a * l2.a + l1.b * l2.b));} 68 | 69 | int main(){ 70 | point A,B,I; 71 | line l1; 72 | scanf("%lf %lf",&(A.x),&(A.y)); 73 | scanf("%lf %lf",&(B.x),&(B.y)); 74 | points_to_line(A,B,&l1); 75 | printf("%.3flx + %.3fly + %.3fl = 0\n",l1.a,l1.b,l1.c); 76 | } 77 | -------------------------------------------------------------------------------- /data_structure/linked_list/linked_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | Singly Linked List. 3 | 4 | This code was not written by me, could not find the original sources. 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | struct elem { 14 | int pos; 15 | struct elem *next; 16 | }; 17 | 18 | static void panic(const char *serror) 19 | { 20 | printf("%s", serror); 21 | exit(1); 22 | } 23 | 24 | static void *xmalloc(size_t size) 25 | { 26 | void *ptr; 27 | if (size == 0) 28 | panic("Size is 0!\n"); 29 | ptr = malloc(size); 30 | if (!ptr) 31 | panic("No mem left!\n"); 32 | return ptr; 33 | } 34 | 35 | static void xfree(void *ptr) 36 | { 37 | if (ptr == NULL) 38 | panic("Got Null-Pointer!\n"); 39 | free(ptr); 40 | } 41 | 42 | static struct elem *init_list(size_t len) 43 | { 44 | // 45 | struct elem *head = xmalloc( sizeof (struct elem) ); 46 | head->pos = 1; 47 | 48 | struct elem *tail = head; 49 | int i; 50 | for (i = 2; i <= 10; i++) { 51 | struct elem *to = xmalloc( sizeof (struct elem) ); 52 | to->pos = i; 53 | tail->next = to; 54 | tail = to; 55 | } 56 | tail->next = head; 57 | 58 | return head; 59 | // 60 | } 61 | 62 | static void clean_list(struct elem *head, size_t len) 63 | { 64 | // 65 | struct elem *ptr = NULL; 66 | while (len > 0) { 67 | if (len > 0) 68 | ptr = head->next; 69 | xfree(head); 70 | if (len > 0) 71 | head = ptr; 72 | len--; 73 | } 74 | // 75 | } 76 | 77 | static void traverse_list(struct elem *head, int times) 78 | { 79 | // 80 | int i; 81 | for (i = 1; i <= times; i++) { 82 | struct elem *ptr = head; 83 | do { 84 | printf("iter: %d, pos: %d\n", i, ptr->pos); 85 | ptr = ptr->next; 86 | } while (ptr != head); 87 | } 88 | // 89 | } 90 | 91 | int main(void) 92 | { 93 | struct elem *head = NULL; 94 | size_t len = 10; 95 | 96 | // 97 | head = init_list(len); 98 | traverse_list(head, 2); 99 | clean_list(head, len); 100 | // 101 | 102 | return 0; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /dynamic_programming/RMQ/RMQ_sparse_table.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Range Minimum Query using Sparse Tables. 3 | 4 | Determines the (position of) the largest value in i..j of an ordered array 5 | of numbers. 6 | 7 | O(nlogn) preprocessing time. 8 | O(1) for each query. 9 | 10 | Input: 11 | n q (number of values, number of queries) 12 | n times v_i 13 | q times a_i b_i 14 | 15 | (c) 2015 Josef Ziegler 16 | 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | // #define NDEBUG 33 | #include "assert.h" 34 | #include "string.h" 35 | #define MP make_pair 36 | #define COMMENT 0 37 | #define MAXN 100001 38 | using namespace std; 39 | 40 | typedef unsigned uint; 41 | typedef long long int llint; 42 | typedef pair PII; 43 | 44 | int A[MAXN]; 45 | int M[MAXN][66]; 46 | int n,q; 47 | 48 | int l2(int x){ // round down 49 | int cnt=0; 50 | while (x>1){ 51 | cnt++; 52 | x>>=1; 53 | } 54 | return cnt; 55 | } 56 | 57 | int RMQ(int a, int b){ 58 | int k=l2(b-a+1); 59 | if (A[M[a][k]]>A[M[b-(1<A[M[i+(1<<(j-1))][j-1]]) 76 | M[i][j]=M[i][j-1]; 77 | else 78 | M[i][j]=M[i+(1<<(j-1))][j-1]; 79 | 80 | #if COMMENT 81 | printf("\nRMQ\n"); 82 | for (int i=0; i 9 | #include 10 | #include 11 | #define MAXV 100 + 1 12 | using namespace std; 13 | 14 | int dist[MAXV]; 15 | vector edges[MAXV]; /* adjacency info */ 16 | int parent[MAXV]; /* discovery relation */ 17 | bool discovered[MAXV]; /* which vertices have been found */ 18 | bool processed[MAXV]; /* which vertices have been processed */ 19 | int nedges, nvertices; /* number of edges and number of vertices in graph */ 20 | 21 | void process_vertex(int v){ 22 | printf("processed vertex %d\n",v); 23 | } 24 | void process_edge(int x, int y){ 25 | printf("processed edge (%d,%d)\n",x,y); 26 | nedges++; 27 | } 28 | 29 | void read(){ 30 | int m,x,y; 31 | nedges=0; 32 | scanf("%d %d",&nvertices,&m); 33 | for (int i=1; i<=m; i++){ 34 | scanf("%d %d",&x,&y); // directed 35 | edges[x].push_back(y); 36 | } 37 | } 38 | 39 | 40 | void bfs(int start){ 41 | queue Q; /* queue of vertices to visit */ 42 | Q.push(start); 43 | discovered[start]=true; 44 | dist[start]=0; 45 | while (Q.empty()==false){ 46 | int v=Q.front(); // current vertex 47 | Q.pop(); 48 | process_vertex(v); 49 | processed[v]=true; 50 | if (dist[v]==-1) 51 | dist[v]=dist[parent[v]]+1; 52 | for (vector::iterator it=edges[v].begin(); it!=edges[v].end(); ++it){ 53 | int y=*it; 54 | if (discovered[y]==false){ 55 | Q.push(y); 56 | discovered[y]=true; 57 | parent[y]=v; 58 | } 59 | if (processed[y]==false) 60 | process_edge(v,y); 61 | } 62 | } 63 | } 64 | 65 | void init(){ 66 | memset(discovered,0,sizeof discovered); 67 | memset(processed,0,sizeof processed); 68 | memset(dist,-1,sizeof dist); 69 | memset(parent,-1,sizeof parent ); 70 | for (int i=0; i 12 | #include 13 | #define MAXV 1000+1 14 | #define MAXDEGREE 100 15 | using namespace std; 16 | 17 | int edges[MAXV][MAXDEGREE]; /* adjacency info */ 18 | int degree[MAXV]; /* outdegree of each vertex */ 19 | int parent[MAXV]; /* discovery relation */ 20 | bool discovered[MAXV]; /* which vertices have been found */ 21 | bool processed[MAXV]; /* which vertices have been processed */ 22 | int nedges, nvertices; /* number of edges and vertices of graph */ 23 | bool finished=false; 24 | 25 | void init(){ 26 | memset(discovered,0,sizeof discovered); 27 | memset(processed,0,sizeof processed); 28 | memset(parent,-1,sizeof parent); 29 | memset(degree,0,sizeof degree); 30 | finished=false; 31 | nedges=0; 32 | } 33 | 34 | void process_edge(int x, int y){ 35 | } 36 | 37 | void process_vertex(int v){ 38 | printf("%d ",v); 39 | } 40 | 41 | bool valid_edge(int v){ 42 | return true;} 43 | 44 | void dfs(int v){ 45 | int y; 46 | if (finished) return; 47 | discovered[v]=true; 48 | process_vertex(v); 49 | for (int i=0; i 30 | #include 31 | #define MAXV 1001 32 | #define MAXINT 1000000000 33 | using namespace std; 34 | 35 | int weight[MAXV][MAXV]; /* adjacency/weight info */ 36 | int nvertices; /* number of vertices in graph */ 37 | 38 | void init(){ 39 | nvertices=0; 40 | for (int i=0; i 9 | #include 10 | #include 11 | #define MATCH 0 12 | #define INSERT 1 13 | #define DELETE 2 14 | #define MAXLEN 100 15 | using namespace std; 16 | 17 | int opt[3]; /* cost of the three options */ 18 | typedef struct { 19 | int cost; /* cost of reaching this cell */ 20 | int parent; /* parent cell */ 21 | } cell; 22 | cell m[MAXLEN+1][MAXLEN+1]; /* dynamic programming table */ 23 | 24 | void row_init(int i){ 25 | m[0][i].cost = i; 26 | if (i>0) 27 | m[0][i].parent=INSERT; 28 | else 29 | m[0][i].parent=-1; 30 | } 31 | 32 | void column_init(int i){ 33 | m[i][0].cost = i; 34 | if (i>0) 35 | m[i][0].parent=DELETE; 36 | else 37 | m[i][0].parent=-1;} 38 | 39 | int match(char c, char d){ 40 | if (c==d) return 0; 41 | else return 1000000;} 42 | 43 | int indel(char c){ 44 | return 1;} 45 | 46 | void goal_cell(char * s, char * t, int * i, int * j){ 47 | *i = strlen(s)-1; 48 | *j = strlen(t)-1;} 49 | 50 | int string_comp(char * s, char * t){ 51 | for (int p=0; p 16 | #include 17 | #include "string.h" 18 | #define MAXN 100000 19 | using namespace std; 20 | 21 | int MaxVal; /* maximum value with a non-zero frequency */ 22 | int F[MAXN]; /* frequency of value with index i (1<= i <= MaxVal) */ 23 | int C[MAXN]; /* cumulative frequency for index i (F[1] + ... + F[i]) */ 24 | int T[MAXN]; /* sum of frequencies stored in BIT with index i from ( i-2^r+1 ) to i 25 | r := index of the last non-zero digit 26 | */ 27 | /* In the following I will use "(idx & -idx)" to isolate the last non-zero digit of idx */ 28 | 29 | /* read cumulative frequency */ 30 | int read(int idx){ 31 | int sum=0; 32 | while (idx>0){ 33 | sum+=T[idx]; 34 | idx-=(idx & -idx); 35 | } 36 | return sum; 37 | } 38 | 39 | /* change frequency and update T */ 40 | void update(int idx, int val){ 41 | while (idx <= MaxVal){ 42 | T[idx]+=val; 43 | idx+=(idx & -idx); 44 | } 45 | } 46 | 47 | /* read the actual frequency at a position */ 48 | /* easy method: return read(idx)-read(idx-1) */ 49 | int readSingle(int idx){ 50 | int sum=T[idx]; /* sum will be decreased */ 51 | if (idx > 0){ /* special case */ 52 | int z=idx-(idx & -idx); /* make z first */ 53 | idx--; /* idx is used as y (predecessor of idx) */ 54 | while (idx != z){ /* at some iteration idx (y) will become z */ 55 | sum -= T[idx]; /* subtract T frequency which is between y and "the same path" */ 56 | idx -= (idx & -idx); 57 | } 58 | } 59 | return sum; 60 | } 61 | 62 | 63 | int main(){ 64 | memset(F,0,sizeof F); memset(C,0,sizeof C); memset(T,0,sizeof T); 65 | 66 | scanf("%d",&MaxVal); 67 | for (int i=1; i<=100; i++) update(i,i); 68 | printf("Ready\n"); 69 | 70 | while (1){ 71 | int a,b; 72 | scanf("%d %d",&a,&b); 73 | printf("%d\n",read(b)-read(a)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /dynamic_programming/edit_distance/edit_dist.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Edit Distance. 3 | 4 | Computes the edit distance of two strings. 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #define MATCH 0 14 | #define INSERT 1 15 | #define DELETE 2 16 | #define MAXLEN 100 17 | using namespace std; 18 | 19 | int opt[3]; /* cost of the three options */ 20 | typedef struct { 21 | int cost; /* cost of reaching this cell */ 22 | int parent; /* parent cell */ 23 | } cell; 24 | cell m[MAXLEN+1][MAXLEN+1]; /* dynamic programming table */ 25 | 26 | void row_init(int i){ 27 | m[0][i].cost = i; 28 | if (i>0) 29 | m[0][i].parent=INSERT; 30 | else 31 | m[0][i].parent=-1; 32 | } 33 | 34 | void column_init(int i){ 35 | m[i][0].cost = i; 36 | if (i>0) 37 | m[i][0].parent=DELETE; 38 | else 39 | m[i][0].parent=-1;} 40 | 41 | int match(char c, char d){ 42 | if (c==d) return 0; 43 | else return 1;} 44 | 45 | int indel(char c){ 46 | return 1;} 47 | 48 | void goal_cell(char * s, char * t, int * i, int * j){ 49 | *i = strlen(s)-1; 50 | *j = strlen(t)-1;} 51 | 52 | int string_comp(char * s, char * t){ 53 | for (int p=0; p 14 | #include 15 | #include 16 | #define MAXN 9 17 | #define MAXIND 32 18 | using namespace std; 19 | 20 | 21 | void initialize(int M[MAXIND] ){ 22 | memset(M,0,MAXIND*sizeof(int)); 23 | } 24 | 25 | // b and e denote beginning and end of interval (inclusive), usually b=0, e=N-1 26 | // add interval [i,j] 27 | void add_interval(int node, int b, int e, int M[MAXIND], int i, int j){ 28 | if (i>e || j=i && e<=j) { 30 | M[node]++; 31 | return; 32 | } 33 | add_interval(2*node , b, (b+e)/2, M, i, j); 34 | add_interval(2*node+1, (b+e)/2 +1, e, M, i, j); 35 | } 36 | 37 | // initialize A to zero before calling this function 38 | // (version 2) takes O(n log n) 39 | void save_interval(int node, int b, int e, int M[MAXIND], int A[MAXN]){ 40 | if (M[node]>=1) { 41 | for (int k=b; k<=e; ++k) A[k]=1; // A[k]+=M[node]; (version 2) 42 | return; // no return (version 2) 43 | } 44 | if (b==e) return; 45 | save_interval(node*2, b, (b+e)/2, M, A); 46 | save_interval(node*2+1, (b+e)/2+1, e, M, A); 47 | } 48 | 49 | int main(){ 50 | // call both functions with node=1, b=0, e=N-1 51 | int M[MAXIND], a, b; 52 | initialize(M); 53 | while (1){ 54 | scanf("%d %d",&a, &b); // read interval which will be stored 55 | add_interval(1, 0, MAXN-1, M, a, b); 56 | 57 | /* for printing */ 58 | int A[MAXIND]; 59 | for (int i=0; i0 && !found) { 69 | found=true; 70 | printf("[%d ",i); 71 | } 72 | if (found && (A[i]==0)) { 73 | printf("%d] ",i-1); 74 | found=false; 75 | } 76 | } 77 | if (found) printf("%d]",MAXN-1); 78 | printf("\n"); 79 | */ 80 | /* end printing */ 81 | } 82 | } 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /graph_theory/dijkstra/dijkstra_O(n**2).cc: -------------------------------------------------------------------------------- 1 | /* 2 | Dijkstra's Algorithm O(n^2). 3 | 4 | Computes the one-source shortest path in weighted graphs in O(n^2). 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | #define MAXINT 1000000000 13 | #define MAXV 1001 14 | #define MAXDEGREE 1001 15 | using namespace std; 16 | 17 | int edges[MAXV][MAXDEGREE]; /* adjacency info */ 18 | int degree[MAXV]; /* outdegree of each vertex */ 19 | int nvertices,nedges; /* number of vertices and edges in graph */ 20 | int parent[MAXV]; /* records tree topology */ 21 | int weight[MAXV][MAXDEGREE];/* edge weight info */ 22 | int Weight; /* edge weight */ 23 | int dist; /* shortest current distance */ 24 | int v,w; /* current vertex to process, candidate next vertex*/ 25 | int Distance[MAXV]; /* vertex Distance from start */ 26 | 27 | void read(){ 28 | int x,y,m,c; 29 | scanf("%d %d",&nvertices,&m); 30 | for (int i=0; i (Distance[v]+Weight)){ 52 | Distance[w]=Distance[v]+Weight; 53 | parent[w]=v;} 54 | } 55 | v=1; 56 | dist=MAXINT; 57 | for (int i=1; i<=nvertices; i++){ 58 | if ((dist > Distance[i]) && (intree[i]==false)){ 59 | v=i; 60 | dist = Distance[i]; 61 | } 62 | } 63 | } 64 | } 65 | 66 | void find_path(int start, int end){ 67 | if ((start==end) || (end==-1)) 68 | printf(" %d\n",start); 69 | else { 70 | find_path(start,parent[end]); 71 | printf(" %d\n",end); 72 | } 73 | } 74 | 75 | 76 | int a,b; 77 | 78 | int main(){ 79 | read(); 80 | for (int i=1; i<=nvertices; i++) 81 | for (int j=0; j 43 | #include 44 | #include 45 | using namespace std; 46 | 47 | char A[1000]; 48 | char B[1000]; 49 | char L[1000][1000]; 50 | int i,j,m; 51 | 52 | int subproblem(int i, int j) 53 | { 54 | if (L[i][j] < 0) { 55 | if (A[i] == '\0' || B[j] == '\0') L[i][j] = 0; 56 | else if (A[i] == B[j]) L[i][j] = 1 + subproblem(i+1, j+1); 57 | else L[i][j] = max(subproblem(i+1, j), subproblem(i, j+1)); 58 | } 59 | return L[i][j]; 60 | } 61 | 62 | int lcs_length(char * A, char * B) 63 | { 64 | /* allocate storage for L; */ 65 | m=max(strlen(A),strlen(B))+1; 66 | for (i = 0; i <= m; i++) 67 | for (j = 0; j <= m; j++) 68 | L[i][j] = -1; 69 | 70 | return subproblem(0, 0); 71 | } 72 | 73 | 74 | int main(){ 75 | scanf("%s %s",A,B); 76 | printf("%d\n",lcs_length(A,B)); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /graph_theory/dinic/dinic.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Dinic's Algorithm (Maxflow/Mincut) O(V^2*E). 3 | 4 | Dinic's algorithm for solving the maximum flow problem. 5 | 6 | (c) 2015 Josef Ziegler 7 | 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | // #define NDEBUG 24 | #include "assert.h" 25 | #include "string.h" 26 | #define MP make_pair 27 | #define COMMENT 1 28 | using namespace std; 29 | 30 | typedef unsigned uint; 31 | typedef long long int llint; 32 | typedef pair PII; 33 | 34 | // the maximum number of vertices 35 | #define NN 1024 36 | 37 | // adjacency matrix (fill this up) 38 | // If you fill adj[][] yourself, make sure to include both u->v and v->u. 39 | int C[NN][NN], deg[NN], adj[NN][NN]; 40 | // BFS stuff 41 | int que[NN], pre[NN]; 42 | 43 | int dinic( int n, int s, int t ){ 44 | int flow = 0; 45 | while( true ){ 46 | // find an augmenting path 47 | memset( pre, -1, sizeof pre); 48 | int qf = 0, qb = 0; 49 | que[qb++] = s; 50 | pre[s]=-2; 51 | while( qf < qb && pre[t] == -1 ) 52 | for( int u = que[qf++], i = 0, v; i < deg[u]; i++ ) 53 | if( pre[v = adj[u][i]] == -1 && C[u][v] ) 54 | pre[que[qb++] = v] = u; 55 | 56 | // see if we're done 57 | if( pre[t] == -1 ) break; 58 | 59 | // try finding more paths 60 | for( int z = 0; z < n; z++ ) if( C[z][t] && pre[z] != -1 ){ 61 | int bot = C[z][t]; 62 | for( int v = z, u = pre[v]; u >= 0; v = u, u = pre[v] ) 63 | bot=min(bot,C[u][v]); 64 | if( !bot ) continue; 65 | 66 | C[z][t] -= bot; 67 | C[t][z] += bot; 68 | for( int v = z, u = pre[v]; u >= 0; v = u, u = pre[v] ){ 69 | C[u][v] -= bot; 70 | C[v][u] += bot;} 71 | flow += bot; 72 | } 73 | } 74 | return flow; 75 | } 76 | 77 | //----------------- EXAMPLE USAGE ----------------- 78 | int main() 79 | { 80 | // read a graph into C[][] 81 | memset( C, 0, sizeof( C ) ); 82 | int n, s, t, m; 83 | scanf( " %d %d %d %d", &n, &s, &t, &m ); 84 | while( m-- ) 85 | { 86 | int u, v, c; scanf( " %d %d %d", &u, &v, &c ); 87 | C[u][v] = c; 88 | } 89 | 90 | // init the adjacency list adj[][] from C[][] 91 | memset( deg, 0, sizeof( deg ) ); 92 | for( int u = 0; u < n; u++ ) 93 | for( int v = 0; v < n; v++ ) if( C[u][v] || C[v][u] ) 94 | adj[u][deg[u]++] = v; 95 | 96 | printf( "%d\n", dinic( n, s, t ) ); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /graph_theory/edmonds_karp/edmonds_karp_adjacency_matrix.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Edmonds-Karp's Algorithm (Maxflow/Mincut) O(V*E^2). 3 | 4 | Edmonds-Karp's algorithm using Ford Fulkerson's method. Implementation uses 5 | adjacency matrices (implemented as 2D arrays) and vertex capacities of inf. 6 | 7 | Max-flow-min-cut theorem: a flow is maximum if and only if its residual 8 | network contains no augmenting path => |f|=c(S,T) for some cut (S,T) of G. 9 | 10 | (c) 2015 Josef Ziegler 11 | 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #define MAXV 1000 20 | #define inf 0x3f3f3f3f 21 | using namespace std; 22 | 23 | int N,E; /* number of vertices and edges */ 24 | int C[MAXV][MAXV]; /* adjacency matrix, C[a][b] means edge (a,b) has a capacity of C[a][b] */ 25 | 26 | int edmonds_karp(int source,int sink){ 27 | int flow[MAXV][MAXV]; /* adjacency matrix: flow */ 28 | int pre[MAXV],p,que[MAXV],q; /* que: a queue */ 29 | int d[MAXV]; 30 | 31 | if (source==sink) return inf; 32 | memset(flow,0,sizeof(flow)); /* initialize all flows to zero */ 33 | while (true){ /* while there exists a path p from s to t in the residual network */ 34 | memset(pre,-1,sizeof(pre)); // initialize pre array 35 | d[source]=inf; // set residual capacity of source to infinity 36 | 37 | p=q=0; // initialize index of p pre and que 38 | que[q++]=source; // add source to queue 39 | while(p 12 | #include 13 | #include 14 | #include 15 | #include "string.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "assert.h" 22 | #include 23 | #include 24 | #include 25 | #define MP make_pair 26 | #define COMMENT 0 27 | #define inf 1000000000 28 | #define MAXV 10000 29 | #define MAXE 50000 30 | #define MAXL MAXV+4*MAXE (+MAXV) 31 | using namespace std; 32 | 33 | typedef pair PII; 34 | typedef long long llint; 35 | 36 | // input restriction: undirected graph, no self-loops 37 | 38 | int n,m; 39 | map M; //( (a,b),(c,f)) edge a to b with capacity c and flow f 40 | vector V[2*(MAXV+1)]; // all capacities are equal 1 41 | 42 | void e(int a, int b, int c){ 43 | V[a].push_back(b); 44 | M.insert(MP(MP(a,b),MP(c,0))); 45 | } 46 | 47 | int edmonds_karp(int source, int sink){ 48 | int pre [2*(MAXV+1)],que[2*(MAXV+1)],d[2*(MAXV+1)],p,q; 49 | if (sink==source) return inf; 50 | while (1){ 51 | memset(pre,-1,sizeof pre); 52 | p=q=0; 53 | d[source]=inf; 54 | que[q++]=source; 55 | while (p::iterator it=V[t].begin(); it!=V[t].end(); it++){ 58 | PII edge=M[MP(t,*it)]; 59 | if (pre[*it]<0 and (tmp=edge.first-edge.second)){ 60 | d[*it]=min(d[t],tmp); 61 | pre[*it]=t; 62 | que[q++]=*it;} 63 | } 64 | } 65 | if (pre[sink]<0) break; 66 | for (int i=sink; i!=source; i=pre[i]){ 67 | M[MP(pre[i],i)].second+=d[sink]; 68 | M[MP(i,pre[i])].second-=d[sink]; 69 | } 70 | } 71 | 72 | int sol=0; 73 | for (vector::iterator it=V[source].begin(); it!=V[source].end(); it++){ 74 | sol+=M[MP(source,*it)].second;} 75 | return sol; 76 | } 77 | 78 | int main(){ 79 | int s,t; 80 | scanf("%d %d",&n,&m); 81 | scanf("%d %d",&s,&t); 82 | M.clear(); 83 | for (int i=0; i<=2*(n+1); i++) V[i].clear(); 84 | for (int i=0; i 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #define MP make_pair 24 | #define COMMENT 0 25 | #define MAX 10001 26 | using namespace std; 27 | 28 | typedef pair PII; 29 | int M,N; 30 | char A[MAX+1][MAX+1]; 31 | int c[MAX+1][MAX+1]; 32 | int best; 33 | PII a1,a2; 34 | 35 | int main(){ 36 | /* INITIALIZE */ 37 | memset(c,0,sizeof c); 38 | 39 | /* INPUT */ 40 | scanf("%d %d",&M,&N); 41 | for (int i=0; i=0; i--) 55 | for (int j=N-1; j>=0; j--) 56 | if (A[i][j]-'0') c[i][j]=c[i][j+1]+1; 57 | else c[i][j]=0; 58 | 59 | #if COMMENT 60 | printf("cache\n"); 61 | for (int i=0; i S; 73 | S.push(MP(-42,-42)); 74 | for (int j=0; jS.top().first) S.push(MP(c[i][j],i)); 78 | else { 79 | int last; 80 | while (c[i][j]best){ 83 | best=tmp; 84 | a1=MP(S.top().second,j); // y and x 85 | a2=MP(i-1,j+S.top().first-1); 86 | } 87 | last=S.top().second; 88 | S.pop(); 89 | } 90 | if (c[i][j]>0) S.push(MP(c[i][j],last)); 91 | } 92 | } 93 | } 94 | printf("%d at [x1,y1][x2,y2] (%d, %d) (%d, %d)\n",best,a1.second+1,a1.first+1,a2.second+1,a2.first+1); 95 | #if COMMENT 96 | printf("\n"); 97 | for (int i=a1.first; i<=a2.first; i++){ 98 | for (int j=a1.second; j<=a2.second; j++){ 99 | printf("%c",A[i][j]); 100 | } 101 | printf("\n"); 102 | } 103 | #endif 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /graph_theory/hierholzer/hierholzer.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Hierholzer's Algorithm (Euler Tour Construction) ( O(E+V) ). 3 | 4 | Euler tour construction O(|E|+|V|) (tour: starting and end points may be 5 | diifferent, circuit: same starting and endpoint). 6 | An adjacency matrix is used, since edges need to be deleted in O(1) to 7 | guarantee linear time complexity. 8 | 9 | A graph has an Eulerian circuit if and only if it is connected (once you 10 | throw out all nodes of degree 0) and every node has `even degree'. 11 | A graph has an Eulerian path if and only if it is connected and every node 12 | except two has even degree. In the second case, one of the two nodes which 13 | has odd degree must be the start node, while the other is the end node. 14 | 15 | USACO pseudocode: 16 | # circuit is a global array 17 | find_euler_circuit 18 | circuitpos = 0 19 | find_circuit(node 1) 20 | 21 | # nextnode and visited is a local array 22 | # the path will be found in reverse order 23 | 24 | find_circuit(node i) 25 | if node i has no neighbors then 26 | circuit(circuitpos) = node i 27 | circuitpos = circuitpos + 1 28 | else 29 | while (node i has neighbors) 30 | pick a random neighbor node j of node i 31 | delete_edges (node j, node i) 32 | find_circuit (node j) 33 | circuit(circuitpos) = node i 34 | circuitpos = circuitpos + 1 35 | 36 | 37 | (c) 2015 Josef Ziegler 38 | 39 | */ 40 | 41 | #include 42 | #include 43 | #include 44 | using namespace std; 45 | 46 | #define NVERTICES 100 47 | 48 | int n=99; // number of distinct vertices 49 | int cp; 50 | int C[NVERTICES*NVERTICES]; 51 | char G[NVERTICES][NVERTICES]; 52 | int Gdeg[NVERTICES]; 53 | 54 | void deledge(int a, int b){ 55 | G[a][b]=0; 56 | G[b][a]=0; 57 | --Gdeg[a]; 58 | --Gdeg[b]; 59 | // printf("edge (%d %d) deleted\n",a,b); 60 | } 61 | void addedge(int a, int b){ 62 | G[a][b]=1; 63 | G[b][a]=1; 64 | ++Gdeg[a]; 65 | ++Gdeg[b]; 66 | // printf("edge (%d %d) added\n",a,b); 67 | } 68 | void findcircuit(int s){ 69 | if (!Gdeg[s]) C[cp++]=s; 70 | else { 71 | for (int i=1; i<=n&&Gdeg[s]>0; i++){ 72 | if (!G[s][i]) continue; 73 | deledge(s,i); // delete edge 74 | findcircuit(i); 75 | } 76 | C[cp++]=s; 77 | } 78 | } 79 | void findeulercircuit(){ // to find an euler tour, simply call this function with one of the two vertices which has an odd degree 80 | memset(C,0,sizeof 0); 81 | cp=0; 82 | findcircuit(1); // starting from node 1 83 | } 84 | int main(){ 85 | int a,b; 86 | memset(G,0,sizeof G); 87 | while (scanf("%d %d",&a,&b)==2) addedge(a,b); 88 | findeulercircuit(); 89 | for (int i=0; i 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #define MP make_pair 47 | #define CMNT 1 48 | #define INF 0x3fffffff 49 | #define MM(s,a) memset((s),(a),sizeof((s))) 50 | using namespace std; 51 | 52 | typedef unsigned uint; 53 | typedef long long int llint; 54 | typedef pair PII; 55 | typedef pair PDD; 56 | 57 | int id[100001]; // id[i]: parent of i 58 | int sz[100001]; // sz[i]: count number of elements in the tree rooted at i 59 | 60 | void initialize(int *A, int *S, int N){ 61 | for (int i=0; i 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "string.h" 32 | #define MP make_pair 33 | #define COMMENT 0 34 | #define MAX 1000+2 35 | using namespace std; 36 | 37 | typedef unsigned uint; 38 | typedef long long int llint; 39 | typedef pair PII; 40 | 41 | int S[MAX][MAX],M,N,best; 42 | char A[MAX][MAX]; 43 | PII a1,a2; 44 | 45 | // indexing 1..N (inclusive) 46 | 47 | int main(){ 48 | /* INPUT */ 49 | scanf("%d %d",&M,&N); 50 | for (int i=1; i<=M; i++) scanf("%s",&A[i][1]); 51 | 52 | #if COMMENT 53 | printf("INPUT\n"); 54 | printf(" "); 55 | for (int j=1; j<=N; j++) printf("%d",j%10); 56 | printf("\n"); 57 | for (int i=1; i<=M; i++){ 58 | printf("%d ",i%10); 59 | for (int j=1; j<=N; j++){ 60 | printf("%1d",A[i][j]-'0'); 61 | } 62 | printf("\n"); 63 | } 64 | printf("\n"); 65 | #endif 66 | /* INITIALIZE */ 67 | memset(S,0,sizeof S); 68 | 69 | /* SUM MATRIX */ 70 | for (int i=1; i<=M; i++) 71 | for (int j=1; j<=N; j++) 72 | S[i][j]=A[i][j]-'0'+S[i-1][j]+S[i][j-1]-S[i-1][j-1]; 73 | 74 | #if COMMENT 75 | printf("SUM MATRIX\n"); 76 | for (int i=1; i<=M; i++){ 77 | for (int j=1; j<=N; j++){ 78 | printf("%4d",S[i][j]); 79 | } 80 | printf("\n"); 81 | } 82 | printf("\n"); 83 | #endif 84 | 85 | /* ALL POSITIONS */ 86 | best=0; 87 | for (int i=0; i<=M; i++) 88 | for (int j=0; j<=N; j++) 89 | for (int k=i+1; k<=M; k++) 90 | for (int l=j+1; l<=N; l++){ 91 | int tmp=S[k][l]+S[i][j]-S[k][j]-S[i][l]; 92 | if (tmp==(k-i)*(l-j)) 93 | if (tmp>best){ 94 | best=tmp; 95 | a1=MP(i+1,j+1); // inclusive +1 96 | a2=MP(k,l);} 97 | } 98 | 99 | printf("%d at [x1,y1][x2,y2] (%d, %d) (%d, %d)\n",best,a1.second,a1.first,a2.second,a2.first); 100 | 101 | #if COMMENT 102 | for (int i=a1.first; i<=a2.first; i++){ 103 | for (int j=a1.second; j<=a2.second; j++) 104 | printf("%c",A[i][j]); 105 | printf("\n"); 106 | } 107 | #endif 108 | } 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /graph_theory/kruskal/kruskal.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Kruskal's Algorithm (Minimum Spanning Tree) O(n log n). 3 | 4 | (c) 2015 Josef Ziegler 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #define MP make_pair 32 | #define CMNT 1 33 | #define INF 0x3fffffff 34 | #define MM(s,a) memset((s),(a),sizeof((s))) 35 | using namespace std; 36 | 37 | typedef unsigned uint; 38 | typedef long long int llint; 39 | typedef pair PII; 40 | typedef pair PDD; 41 | typedef pair PIP; 42 | 43 | vector id; // id[i]: id of vertex i (used for union-find) 44 | vector sz; // sz[i]: size of the component containing vertex i 45 | vector > V; 46 | 47 | void initialize(vector &id, vector &sz, int N){ 48 | for (int i=0; i &id, int i){ 54 | while (id[i]!=i){ 55 | id[i]=id[id[i]]; // path compression 56 | i=id[i];} 57 | return i; 58 | } 59 | 60 | bool find(vector &id, int p, int q){ // are p and q in the same set? 61 | return root(id,p)==root(id,q); 62 | } 63 | 64 | void unite(vector &id, vector &sz, int p, int q){ // merge sets containing i and j 65 | int i=root(id,p); 66 | int j=root(id,q); 67 | if (sz[i] S; 74 | int sol=0; 75 | for (int i=0; i::iterator it=V[i].begin(); it!=V[i].end(); it++) 77 | S.insert(MP(it->second,MP(i,it->first))); 78 | while (!S.empty()){ 79 | PIP v=*S.begin(); 80 | S.erase(S.begin()); 81 | // printf("at %d %d cost %d\n",v.second.first,v.second.second,v.first); 82 | if (!(find(id,v.second.first,v.second.second))){ 83 | sol+=v.first; 84 | unite(id,sz,v.second.first,v.second.second); 85 | } 86 | } 87 | return sol; 88 | } 89 | 90 | int N,M; 91 | 92 | int main(){ 93 | scanf("%d %d",&N,&M); 94 | 95 | id.resize(N+1); 96 | sz.resize(N+1); 97 | V.resize(N+1); 98 | initialize(id,sz,N); 99 | 100 | for (int i=0; i 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #define INF 1e9 19 | #define EPSILON (1e-7) 20 | #define MAXN 100000 21 | #define PDD pair 22 | using namespace std; 23 | 24 | int N; /* number of points */ 25 | vector< PDD > V; /* vector of N points, x-, and y-coordinate */ 26 | PDD F; /* first hull point, the one with the lowest y coordinate 27 | (if there's a tie -> lowest x coordinate) */ 28 | PDD S; 29 | PDD C[MAXN]; /* convex hull */ 30 | map< PDD , bool> M; 31 | /* A := signed area of triangle: p1p2 x p1p3 32 | if A > 0 => ccw, if A < 0 => cw */ 33 | bool ccw(PDD a, PDD b, PDD c){ 34 | return (b.first-a.first) * (c.second-a.second) - (c.first-a.first) * (b.second-a.second) >= 0;} 35 | 36 | bool collinear(PDD a, PDD b, PDD c){ 37 | /* signed triangle area */ 38 | double tmp=(b.first-a.first) * (c.second-a.second) - (c.first-a.first) * (b.second-a.second); 39 | return (tmp-EPSILON);} 40 | 41 | double dist(PDD a, PDD b){ 42 | return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));} 43 | 44 | bool sortop(PDD a, PDD b){ 45 | if (collinear(F,a,b)) 46 | if (dist(F,a) < dist(F,b)) return 1; 47 | else return 0; 48 | if (ccw(F,a,b)) return 1; 49 | else return 0; 50 | } 51 | 52 | int main(){ 53 | /* input handling */ 54 | scanf("%d",&N); 55 | for (int i=0; i (INF,INF); 66 | for (int i=0; i 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #define MP make_pair 35 | #define CMNT 0 36 | #define INF 0x3fffffff 37 | #define MM(s,a) memset((s),(a),sizeof((s))) 38 | using namespace std; 39 | 40 | typedef unsigned uint; 41 | typedef long long int llint; 42 | typedef pair PII; 43 | typedef pair PDD; 44 | 45 | int N; // number of points 46 | struct pt{ 47 | double x; 48 | double y; 49 | } A[40001]; 50 | 51 | struct obj1{ 52 | bool operator() (pt a, pt b){ if (a.x==b.x) {return a.y S; // needs to be multiset, since points with same coords are allowed 64 | 65 | double d; 66 | 67 | int main(){ 68 | // while (1){ 69 | // initialize 70 | S.clear(); 71 | // read input 72 | scanf("%d",&N); 73 | if (!N) return 0; 74 | for (int i=0; i S: maintain an active set of points - candidates to be a closest-pair with the current point. 78 | // the set is ordered by the y coordinate 79 | int back=0; 80 | d=dist(A[0],A[1]); 81 | S.insert(A[0]); S.insert(A[1]); 82 | // C. line sweep the points by x order 83 | for (int i=2; i::iterator pos=S.find(A[i]),tmp; 86 | // C-1. scan the active set for points that may be closer to the current point than the shortest distance 87 | // compare with ones above A[i] 88 | tmp=pos; 89 | tmp++; 90 | while (tmp!=S.end() && (tmp->y-pos->y)y-tmp->y)d && back 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | // #define NDEBUG 30 | #include "assert.h" 31 | #include "string.h" 32 | #define MP make_pair 33 | #define COMMENT 1 34 | #define MAX 50001 35 | using namespace std; 36 | 37 | typedef unsigned uint; 38 | typedef long long int llint; 39 | typedef pair PII; 40 | 41 | int N,M,a,b; 42 | int parent[MAX]; 43 | vector G[MAX]; 44 | vector back[MAX]; /* back edges */ 45 | bool B[MAX]; 46 | int DFN[MAX],L[MAX]; /* DFN[i] time at which i is visited (starting with 1), L[i] smallest DFN value which can be visited from i through a special path, if none exists L[i]=DFN[i] */ 47 | int num; 48 | vector arc; // for counting articulation points 49 | 50 | 51 | void dfs_artic(int s){ 52 | B[s]=true; 53 | for (vector :: iterator it=G[s].begin(); it!=G[s].end(); it++){ 54 | if (!B[*it]) { 55 | DFN[*it]=num++; 56 | L[*it]=DFN[*it]; 57 | parent[*it]=s; 58 | dfs_artic(*it); // recursion 59 | // check if s is an articulation point, that is, all vertices other than root 60 | if (s!=0 && DFN[s]<=L[*it]) arc.push_back(s); 61 | } 62 | else { 63 | if (*it!=parent[s]) { // back edge 64 | back[s].push_back(*it); 65 | L[s]=min(L[s],DFN[*it]); 66 | } 67 | } 68 | } 69 | // todo: not execute for root 70 | L[parent[s]]=min(L[parent[s]],L[s]); // update parent 71 | 72 | } 73 | 74 | 75 | 76 | int main(){ 77 | scanf("%d %d",&N,&M); 78 | for (int i=0; i::iterator it=back[i].begin(); it!=back[i].end(); it++) 98 | printf("%d ",*it); 99 | printf("\n"); 100 | } 101 | printf("\n"); 102 | printf("vertex no. i, DFN[i], L[i]\n"); 103 | for (int i=0; i1) { 110 | arc.push_back(0);} 111 | printf("there are %d articulation points\n",arc.size()); 112 | for (vector::iterator it=arc.begin(); it!=arc.end(); it++) 113 | printf("%d\n",*it); 114 | } 115 | 116 | -------------------------------------------------------------------------------- /algebra/bignum/prog_challenges/bignum_nosignbit.cc: -------------------------------------------------------------------------------- 1 | /* 2 | High-Precision Arithmetic in C++ implemented with Arrays of Digits. 3 | 4 | Adapted from the book "Programming Challenges" by Steven S. Skiena and 5 | Miguel A. Revilla, 2003, Springer. 6 | 7 | (c) 2015 Josef Ziegler 8 | 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | #define MAXDIGITS 1000 /* maximum length bignum */ 16 | 17 | typedef struct { 18 | char D[MAXDIGITS]; /* represents the number (least significant to most significant) */ 19 | int ld; /* index of high-order digit */ 20 | } bignum; 21 | 22 | void print_bignum(bignum &N){ 23 | for (int i=N.ld; i>=0; i--) printf("%c",'0'+ N.D[i]); 24 | printf("\n"); 25 | } 26 | 27 | void initialize_bignum(bignum &A){ 28 | A.ld=0; 29 | memset(A.D,0,MAXDIGITS); 30 | } 31 | 32 | void zero_justify(bignum &N){ 33 | while ((N.ld > 0) && (N.D[N.ld]==0)) N.ld--; 34 | } 35 | 36 | void subtract_bignum(bignum &A, bignum &B, bignum &C); 37 | 38 | void add_bignum(bignum &A, bignum &B, bignum &C){ 39 | int carry=0; /* carry digit */ 40 | initialize_bignum(C); 41 | C.ld=max(A.ld,B.ld)+1; 42 | /* managing last digit of C */ 43 | for (int i=0; i<=C.ld; i++){ /* actual calculation */ 44 | C.D[i] = (char) (carry+A.D[i]+B.D[i])%10; 45 | carry = (carry + A.D[i] + B.D[i])/10;} 46 | zero_justify(C); /* checks for leading zeros */ 47 | } 48 | 49 | int compare_bignum(bignum &A, bignum &B){ /* A < B ? */ 50 | if (B.ld > A.ld) return 1; /* different */ 51 | if (B.ld < A.ld) return -1; /* length */ 52 | for (int i=A.ld; i>=0; i--){ /* same length */ 53 | if (A.D[i] < B.D[i]) return 1; 54 | if (A.D[i] > B.D[i]) return -1; 55 | } 56 | return 0; 57 | } 58 | 59 | void subtract_bignum(bignum &A, bignum &B, bignum &C){ 60 | int borrow=0; /* anything borrowed? */ 61 | int v; /* placeholder digit */ 62 | initialize_bignum(C); 63 | C.ld=max(A.ld,B.ld); 64 | for (int i=0; i<=C.ld; i++){ 65 | v = A.D[i]-borrow-B.D[i]; 66 | if (A.D[i] > 0) borrow = 0; 67 | if (v < 0) { 68 | v+=10; 69 | borrow = 1;} 70 | C.D[i]=(char)v%10; 71 | } 72 | zero_justify(C); 73 | } 74 | 75 | void digit_shift(bignum &N, int d){ /* multiply n by 10^d */ 76 | if ((N.ld == 0) && (N.D[0] == 0)) return; /* case N->digits = 0 */ 77 | for (int i=N.ld; i>=0; i--) N.D[i+d] = N.D[i]; 78 | for (int i=0; i=0; i--){ 104 | digit_shift(row,1); 105 | row.D[0] = A.D[i]; 106 | C.D[i] = 0; 107 | while (compare_bignum(row,B) != 1){ 108 | C.D[i]++; 109 | subtract_bignum(row,B,tmp); 110 | row = tmp;} 111 | } 112 | zero_justify(C); 113 | } 114 | 115 | void int_to_bignum(int s, bignum &N){ 116 | int i; /* counter */ 117 | int t=abs(s); /* int to work with */ 118 | memset(N.D,0,sizeof N.D); 119 | N.ld=-1; 120 | while (t>0) { 121 | N.ld++; 122 | N.D[N.ld]=t%10; 123 | t/=10;} 124 | if (s==0) N.ld=0; 125 | } 126 | 127 | int main(){ 128 | 129 | } 130 | -------------------------------------------------------------------------------- /data_structure/binary_search_tree/binary_search_tree.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Unbalanced Binary Search Tree (BST). 3 | 4 | The left subtree of a node contains only nodes with keys less than the node's 5 | key. 6 | The right subtree of a node contains only nodes with keys greater than the 7 | node's key. 8 | Both the left and right subtrees must also be binary search trees. 9 | There must be no duplicate nodes. 10 | 11 | 6 12 | 2 7 13 | 1 4 8 14 | 3 15 15 | 12 18 16 | 13 19 22 17 | 18 | 19 | (c) 2015 Josef Ziegler 20 | 21 | */ 22 | 23 | #include 24 | #include 25 | using namespace std; 26 | 27 | class node{ 28 | public: 29 | int key; 30 | node* right; 31 | node* left; 32 | }; 33 | 34 | node* search(int key, node* tnode){ 35 | if (tnode == NULL) 36 | return NULL; 37 | if (tnode->key == key) 38 | return tnode; 39 | else if (key < tnode->key) 40 | return search(key, tnode->left); 41 | else 42 | return search(key, tnode->right); 43 | } 44 | 45 | node* insert(int key, node* tnode){ 46 | if (tnode == NULL){ 47 | tnode = new node; 48 | tnode->key = key; 49 | return tnode; 50 | } 51 | if (key < tnode->key) 52 | tnode->left=insert(key, tnode->left); 53 | else 54 | tnode->right=insert(key, tnode->right); 55 | return tnode; 56 | } 57 | 58 | // returns node with smallest key in subtree with root tnode 59 | // needed for "remove" function 60 | node* get_smallest(node* tnode){ 61 | if (tnode->left != NULL) 62 | return get_smallest(tnode->left); 63 | else 64 | return tnode; 65 | } 66 | // unlinks node with smallest key in subtree with root tnode 67 | // return value: root of modified subtree 68 | // needed for "remove" function 69 | node* unlink_smallest(node* tnode){ 70 | if (tnode->left == NULL && tnode->right == NULL) 71 | return NULL; 72 | if (tnode->left != NULL){ 73 | tnode->left = unlink_smallest(tnode->left); 74 | return tnode; 75 | } 76 | else { 77 | // tnode->left == NULL && tnode->right != NULL 78 | return tnode->right; 79 | } 80 | } 81 | 82 | void BST_print(node*); 83 | // returns the root of the newly created BST 84 | // doesn't check whether element is atcually in BST 85 | node* remove(int key, node* tnode){ 86 | if (tnode == NULL) return NULL; 87 | if (key == tnode->key) { 88 | // if tnode is leaf 89 | if (tnode->right == NULL && tnode->left == NULL){ 90 | delete tnode; 91 | return NULL; 92 | } 93 | // tnode has one child 94 | if (tnode->left == NULL) { 95 | node* tmp=tnode->right; 96 | delete tnode; 97 | return tmp; 98 | } 99 | if (tnode->right == NULL){ 100 | node* tmp=tnode->left; 101 | delete tnode; 102 | return tmp; 103 | } 104 | // tnode has two children 105 | node* smallest=get_smallest(tnode->right); 106 | tnode->right=unlink_smallest(tnode->right); 107 | tnode->key=smallest->key; 108 | delete smallest; 109 | return tnode; 110 | } 111 | else { 112 | if (key < tnode->key) 113 | tnode->left=remove(key,tnode->left); 114 | else 115 | tnode->right=remove(key,tnode->right); 116 | return tnode; 117 | } 118 | } 119 | 120 | // dfs 121 | void BST_print(node* tree){ 122 | if (tree==NULL) return; 123 | if (tree->left!=NULL){ 124 | printf("%d (l)-> %d\n",tree->key, (tree->left)->key); 125 | BST_print(tree->left); 126 | } 127 | if (tree->right!=NULL){ 128 | printf("%d (r)-> %d\n",tree->key, (tree->right)->key); 129 | BST_print(tree->right); 130 | } 131 | } 132 | 133 | int main(){ 134 | int x; 135 | node* ptr = new node; 136 | ptr->key=-1; 137 | 138 | printf("if x positive: insert x\n"); 139 | printf("if x negative: delete x\n"); 140 | while (1){ 141 | scanf("%d",&x); 142 | if (x==0) {printf("x must be negative or positive\n"); continue;} 143 | if (x>0) insert(x,ptr); 144 | if (x<0) ptr=remove(-x,ptr); 145 | BST_print(ptr); 146 | printf("\n"); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /data_structure/suffix_array/suffix_array.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Suffix Array O(n log(n)^2). 3 | 4 | What is a suffix tree/trie, what is a suffix array? 5 | 6 | suffix trie/trie: 7 | 8 | A trie or a suffix tree is meant to store strings. 9 | The number of children of an arbitrary node is equal to the 10 | size of the alphabet (of the strings to be stored). Every edge 11 | going from the father to its sons is labelled with a different 12 | letter of the alphabet. The labels on a path starting from 13 | the root and ending in a leaf form a string stored in that tree. 14 | Those formed strings are suffixes of our original string A (we 15 | consider the string itself also to be a suffix). 16 | 17 | suffix array: 18 | 19 | Given a string A=a_0,a_1,...,a_n-1, denote by A_i=a_i,a_i+1,...,a_n-1 20 | the suffix of A that begins at pos. i. 21 | By doing a DFS of the trie (consider the nodes in the ascending 22 | lexicographic order of the edges linking them to their father) we 23 | get the suffixes of A in sorted (ascending) order (e.g. A_1,A_2,A_0,A_3). 24 | The array which maintains the index of every suffix in the sorted 25 | array is called the suffix array. 26 | 27 | Ex. P = (0, 2, 1, 3) for string abac, 28 | abac = A_0, ac = A_2, bac = A_1, c = A_3 29 | 30 | 31 | ********* 32 | Main idea: 33 | 34 | The algorithm is mainly based on maintaining the order of the string's 35 | suffixes sorted by their 2^k long prefixes. We shall execute 36 | m=ceil(log_2 n) steps, computing the order of the prefixes of length 2^k at 37 | the k-th step. It is used an m x n sized matrix. Let's denote by A_i^k the 38 | subsequence of A of length 2^k starting at pos. i. The pos. of A_i^k in the 39 | sorted array of A_j^k subsequences (j=1,n) is kept in P_(k,i). 40 | 41 | 42 | see "Suffix arrays - a programming contest approach" for more info. 43 | ********* 44 | Complexity: 45 | Using the STL sort function we get O(n log(n)^2). 46 | 47 | 48 | (c) 2015 Josef Ziegler 49 | 50 | */ 51 | 52 | #include 53 | #include 54 | #include // for STL sort 55 | using namespace std; 56 | 57 | struct entry { 58 | int nr[2]; 59 | int p; 60 | }; 61 | 62 | bool cmp(struct entry a, struct entry b) { 63 | if (a.nr[0] == b.nr[0]) 64 | return a.nr[1] < b.nr[1]; 65 | return a.nr[0] < b.nr[0]; 66 | } 67 | 68 | void printstep(int step, entry* L, int** P, int N) { 69 | printf("L[i].nr[0] "); 70 | for (int i = 0; i < N; i++) 71 | printf("%2d ", L[i].nr[0]); 72 | printf("\n"); 73 | 74 | printf("L[i].nr[1] "); 75 | for (int i = 0; i < N; i++) 76 | printf("%2d ", L[i].nr[1]); 77 | printf("\n"); 78 | 79 | printf("L[i].p "); 80 | for (int i = 0; i < N; i++) 81 | printf("%2d ", L[i].p); 82 | printf("\n"); 83 | 84 | printf("P[%d][i] ", step); 85 | for (int i = 0; i < N; i++) { 86 | printf("%2d ",P[step][i]); 87 | } 88 | printf("\n"); 89 | printf("\n"); 90 | } 91 | 92 | void printall(char* A, int** P, int N){ 93 | int k = 0; 94 | for (k = 0; ((1 << k) >> 1) < N; k++); 95 | for (int i = 0; i < N; i++) { 96 | int j; 97 | for (j = 0; j < N; j++) 98 | if (i == P[k][j]) 99 | break; 100 | for (int p = j; p < N; p++) 101 | printf("%c", A[p]); 102 | printf("\n"); 103 | } 104 | printf("\n"); 105 | } 106 | 107 | void suffix_array(char* A) { 108 | int N = strlen(A); 109 | entry* L = new entry[N+2]; 110 | // P[k][i] position of suffix of A that begins 111 | // at position i of length 2^k 112 | int logn = 0; // log_2(n)+1 113 | for (int tmp = N; tmp > 0; tmp /= 2, logn++) ; 114 | logn++; 115 | int** P = new int*[N+2]; // log(n) x n matrix, 116 | for (int i = 0; i < N; i++) 117 | P[i] = new int[logn+2]; 118 | 119 | // STEP 0 120 | for (int i = 0; i < N; i++) 121 | P[0][i]=A[i]-'a'; 122 | // STEP 1 123 | for (int stp = 1, cnt = 1; (cnt >> 1) < N; stp++, cnt <<= 1) { 124 | // stp: step, cnt: 2^(stp-1) if stil < N 125 | for (int i = 0; i < N; i++) { // for every element 126 | L[i].nr[0] = P[stp - 1][i]; 127 | if (i + cnt < N) 128 | L[i].nr[1] = P[stp - 1][i + cnt]; // merge those of same length 129 | else 130 | L[i].nr[1] = -1; // if it doesn't exceed array border 131 | L[i].p = i; // position 132 | } 133 | // step 2 134 | sort(L, L + N, cmp); 135 | // step 3 136 | for (int i = 0; i < N; i++) 137 | P[stp][L[i].p] = (i > 0 && L[i].nr[0] == L[i - 1].nr[0] && L[i].nr[1] == L[i - 1].nr[1]) 138 | ? P[stp][L[i - 1].p] : i; 139 | printstep(stp, L, P, N); 140 | } 141 | printall(A, P, N); 142 | } 143 | 144 | int main(){ 145 | char A[100000]; 146 | scanf("%s",A); 147 | 148 | suffix_array(A); 149 | } 150 | -------------------------------------------------------------------------------- /algebra/bignum/prog_challenges/bignum.cc: -------------------------------------------------------------------------------- 1 | /* 2 | High-Precision Arithmetic implemented with Arrays of Digits. 3 | 4 | Adapted from the book "Programming Challenges" by Steven S. Skiena and 5 | Miguel A. Revilla, 2003, Springer. 6 | 7 | (c) 2015 Josef Ziegler 8 | 9 | */ 10 | 11 | #include "stdio.h" 12 | #include "iostream" 13 | 14 | #define MAXDIGITS 100 /* maximum length bignum */ 15 | #define PLUS 1 /* positive sign bit */ 16 | #define MINUS -1 /* negative sign bit */ 17 | 18 | typedef struct { 19 | char digits[MAXDIGITS]; /* represents the number */ 20 | int signbit; /* PLUS or MINUS */ 21 | int lastdigit; /* index of high-order digit */ 22 | } bignum; 23 | 24 | void print_bignum(bignum *N){ 25 | int i; 26 | if (N->signbit == MINUS) printf("-"); 27 | for (i=N->lastdigit; i>=0; i--) 28 | printf("%c",'0'+ N->digits[i]); 29 | printf("\n");} 30 | 31 | void initialize_bignum(bignum *A){ 32 | A->lastdigit=0; 33 | A->signbit=PLUS; 34 | memset(A->digits,0,MAXDIGITS);} 35 | 36 | void zero_justify(bignum *N){ 37 | while ((N->lastdigit > 0) && (N->digits[N->lastdigit] == 0)) 38 | N->lastdigit--; 39 | if ((N->lastdigit == 0) && (N->digits[0] == 0)) 40 | N->signbit = PLUS;} /* hack to avoid -0 */ 41 | 42 | void subtract_bignum(bignum *A, bignum *B, bignum *C); 43 | void add_bignum(bignum *A, bignum *B, bignum *C){ 44 | int carry=0; /* carry digit */ 45 | int i; /* counter */ 46 | initialize_bignum(C); 47 | 48 | if (A->signbit == B->signbit) C->signbit = A->signbit; /* addition */ 49 | else { /* subtraction */ 50 | if (A->signbit == MINUS){ 51 | A->signbit = PLUS; 52 | subtract_bignum(B,A,C); 53 | A->signbit = MINUS;} 54 | else { 55 | B->signbit = PLUS; 56 | subtract_bignum(A,B,C); 57 | B->signbit = MINUS;} 58 | return;} 59 | 60 | C->lastdigit = (A->lastdigit > B->lastdigit ? A->lastdigit : B->lastdigit) + 1; 61 | /* managing last digit of C */ 62 | for (int i=0; i<=C->lastdigit; i++){ /* actual calculation */ 63 | C->digits[i] = (char) (carry+A->digits[i]+B->digits[i]) % 10; 64 | carry = (carry + A->digits[i] + B->digits[i]) / 10;} 65 | 66 | zero_justify(C); /* checks for leading zeros */ 67 | } 68 | 69 | int compare_bignum(bignum *A, bignum *B){ /* A < B ? */ 70 | int i; /* counter */ 71 | if ((A->signbit == MINUS) && (B->signbit == PLUS)) return(PLUS);/* signbits */ 72 | if ((A->signbit == PLUS) && (B->signbit == MINUS)) return(MINUS); 73 | 74 | if (B->lastdigit > A->lastdigit) return(PLUS * A->signbit); /* different */ 75 | if (B->lastdigit < A->lastdigit) return(MINUS * A->signbit); /* length */ 76 | 77 | for (i = A->lastdigit; i>=0; i--){ /* same length */ 78 | if (A->digits[i] > B->digits[i]) return (MINUS * A->signbit); 79 | if (A->digits[i] < B->digits[i]) return (PLUS * A->signbit);} 80 | 81 | return(0);} 82 | 83 | void subtract_bignum(bignum *A, bignum *B, bignum *C){ 84 | int borrow=0; /* anything borrowed? */ 85 | int v; /* placeholder digit */ 86 | int i; /* counter */ 87 | initialize_bignum(C); 88 | 89 | if ((A->signbit == MINUS) || (B->signbit == MINUS)){ 90 | B->signbit = -1 * B->signbit; 91 | add_bignum(A,B,C); 92 | B->signbit = -1 * B->signbit; 93 | return;} 94 | 95 | if (compare_bignum(A,B) == PLUS){ // A < B 96 | subtract_bignum(B,A,C); 97 | C->signbit = MINUS; 98 | return;} 99 | 100 | C->lastdigit = A->lastdigit > B->lastdigit ? A->lastdigit : B->lastdigit; 101 | 102 | for (i=0; i<=(C->lastdigit); i++){ 103 | v = (A->digits[i] - borrow - B->digits[i]); 104 | if (A->digits[i] > 0) borrow = 0; 105 | if (v < 0) { 106 | v = v + 10; 107 | borrow = 1;} 108 | C->digits[i] = (char) v % 10; 109 | } 110 | zero_justify(C); 111 | } 112 | 113 | void digit_shift(bignum *N, int d){ /* multiply n by 10^d */ 114 | int i; /* counter */ 115 | if ((N->lastdigit == 0) && (N->digits[0] == 0)) return; /* case N->digits = 0 */ 116 | for (i=N->lastdigit; i>=0; i--) N->digits[i+d] = N->digits[i]; 117 | for (i=0; idigits[i] = 0; 118 | N->lastdigit = N->lastdigit + d;} 119 | 120 | void multiply_bignum(bignum *A, bignum *B, bignum *C){ 121 | bignum row; /* respresent shifted row */ 122 | bignum tmp; /* placeholder bignum */ 123 | int i,j; /* counter */ 124 | initialize_bignum(C); 125 | 126 | row = *A; 127 | for (i=0; i<=B->lastdigit; i++){ 128 | for (j=1; j<=B->digits[i]; j++){ 129 | add_bignum(C,&row,&tmp); 130 | *C = tmp;} 131 | digit_shift(&row,1); 132 | } 133 | C->signbit = A->signbit * B->signbit; 134 | zero_justify(C); 135 | } 136 | 137 | void division_bignum(bignum *A, bignum *B, bignum *C){ 138 | bignum row; /* represent shifted row */ 139 | bignum tmp; /* placeholder bignum */ 140 | int asign=A->signbit; /* temporary signs */ 141 | int bsign=B->signbit; 142 | int i,j; /* counters */ 143 | initialize_bignum(C); 144 | C->signbit = A->signbit * B->signbit; 145 | A->signbit = PLUS; 146 | B->signbit = PLUS; 147 | initialize_bignum(&row); 148 | initialize_bignum(&tmp); 149 | C->lastdigit = A->lastdigit; 150 | 151 | for (i=A->lastdigit; i>=0; i--){ 152 | digit_shift(&row,1); 153 | row.digits[0] = A->digits[i]; 154 | C->digits[i] = 0; 155 | while (compare_bignum(&row,B) != PLUS){ 156 | C->digits[i]++; 157 | subtract_bignum(&row,B,&tmp); 158 | row = tmp;} 159 | } 160 | zero_justify(C); 161 | A->signbit = asign; 162 | B->signbit = bsign; 163 | } 164 | 165 | void int_to_bignum(int s, bignum *N){ 166 | int i; /* counter */ 167 | int t; /* int to work with */ 168 | if (s >= 0) N->signbit = PLUS; 169 | else N->signbit = MINUS; 170 | 171 | memset(N->digits,0,sizeof N->digits); 172 | N->lastdigit=-1; 173 | t = abs(s); 174 | while (t>0) { 175 | N->lastdigit++; 176 | N->digits[N->lastdigit] = t % 10; 177 | t = t / 10;} 178 | if (s == 0) N->lastdigit=0; 179 | } 180 | 181 | int main(){ 182 | 183 | } 184 | -------------------------------------------------------------------------------- /algebra/bignum/bignum.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Bignums efficient. 3 | 4 | * base conversion (base 10^BASE10) 5 | * bignum multiplication 6 | * bignum addition 7 | * bignum subtraction (for positive results) 8 | * bignum comparison 9 | * bignum square root (using binary search) 10 | 11 | (c) 2015 Josef Ziegler 12 | 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #define MP make_pair 39 | #define CMNT 0 40 | // your base: 10^BASE10; in order to use multiplication the square of your 41 | // chosen base must fit in a long long; maximum: 18 42 | #define BASE10 9 43 | // in base 10^BASE10, effective number of digits: BASE10*DIGITS 44 | #define DIGITS 12 45 | using namespace std; 46 | 47 | typedef unsigned uint; 48 | typedef long long int llint; 49 | typedef pair PII; 50 | typedef pair PDD; 51 | 52 | struct bignum{ 53 | llint N[DIGITS]; // in base 10^BASE10 54 | int last; 55 | }; 56 | 57 | llint POW10[20]; 58 | // precompute powers of 10 59 | void precomp_pow10(){ 60 | POW10[0]=1; 61 | for (int i=1; i<19; i++) POW10[i]=POW10[i-1]*10; 62 | } 63 | 64 | // omit leading zeros 65 | void zerojustify(bignum& A){ 66 | while (A.last>1 && A.N[A.last-1]==0) A.last--; 67 | } 68 | 69 | // initialize bignum 70 | void init(bignum& A){ 71 | A.last=1; 72 | memset(A.N,0,sizeof A.N); 73 | } 74 | 75 | // bignum assignment 76 | void assign(bignum& A, bignum& B){ // A:=B 77 | A.last=B.last; 78 | for (int i=0; i=0; i--) 86 | for (int j=BASE10-1; j>=0; j--) 87 | printf("%lld",(A.N[i]/POW10[j])%10); 88 | if (newline) printf("\n"); 89 | 90 | } 91 | 92 | // convert integer saved in char string to bignum (base 10^BASE10) 93 | void base(bignum& A, char* Q){ 94 | // manipulate input string such that chars with lowest index are least significant digits 95 | char S[DIGITS*BASE10]; 96 | int s=strlen(Q); 97 | for (int i=0; iB) 131 | void sub(bignum& A, bignum& B, bignum& C){ // C=A-B 132 | bignum sol; 133 | init(sol); 134 | sol.last=max(A.last,B.last); 135 | llint tmp,borrow=0; 136 | for (int i=0; i=0; i--) A.N[i+n]=A.N[i]; 150 | for (int i=n-1; i>=0; i--) A.N[i]=0; 151 | A.last+=n; 152 | } 153 | 154 | // bignum multiplication 155 | void mult(bignum& A, bignum& B, bignum& C){ 156 | bignum tmp,sol; 157 | init(sol); 158 | for (int i=0; iB 182 | if (A.last>B.last) return 1; 183 | if (A.last=0; i--) { 185 | if (A.N[i]>B.N[i]) return 1; 186 | else if (A.N[i]= 10) ++i; 205 | return sol+i+1; 206 | } 207 | 208 | // bignum square root 209 | void sqrt(bignum& A, bignum& C){ // sqrt(A)=C 210 | // A has A.last digits 211 | // the square root of A must have between (digits(A)+1)/2 and (digits(A)+1)/2+1 212 | // whereas digits(A) denotes num. digits in base 10 213 | bignum low,high,mid,sol,one,cmp; 214 | char One[]="1"; base(one,One); 215 | 216 | base(low,One); shift10(low, (digits(A)+1)/2-1); 217 | base(high,One); shift10(high,(digits(A)+1)/2); 218 | 219 | while (comp(high,low)>=0){ 220 | add(high,low,mid); 221 | div2(mid); 222 | mult(mid,mid,cmp); 223 | if (comp(cmp,A)<=0){ 224 | assign(sol,mid); 225 | assign(low,mid); 226 | add(low,one,low);} 227 | else { 228 | assign(high,mid); 229 | sub(high,one,high); 230 | } 231 | } 232 | zerojustify(sol); 233 | assign(C,sol); 234 | } 235 | 236 | char S[BASE10*DIGITS]; 237 | 238 | int main(){ 239 | precomp_pow10(); 240 | 241 | bignum A,B,C; 242 | // test: base conversion and print bignum 243 | scanf("%s",S); 244 | base(A,S); 245 | scanf("%s",S); 246 | base(B,S); 247 | printf("base conversion for A: \n"); 248 | for (int i=0; i