├── Function └── Function.cpp ├── README.md ├── Uses ├── deque.cpp ├── map.cpp ├── pair.cpp ├── priority_queue.cpp ├── queue.cpp ├── set.cpp ├── stack.cpp └── vecto.cpp └── algorithms ├── 2D_BIT.cpp ├── 2D_segment_tree.cpp ├── AVL.cpp ├── Aho_Corasick.cpp ├── BIT.cpp ├── BST.cpp ├── BinarySearch.cpp ├── Bubble_Sort.cpp ├── Bucket_Sort.cpp ├── CatalanNumber.cpp ├── Count_Sort.cpp ├── DAG_min_path.cpp ├── Digit_dp_I.cpp ├── Digit_dp_II.cpp ├── Digit_dp_III.cpp ├── Digit_dp_IV.cpp ├── Dijkstra’s_Shortest_Path.cpp ├── FFT.cpp ├── Finite_Automata_Pattern_Searching.cpp ├── HLD.cpp ├── Huffman_coding.cpp ├── Insertion_Sort.cpp ├── InterpolationSearch.cpp ├── Josephus_Recurrence.cpp ├── JumpSearch.cpp ├── Kruskal’s_Minimum_Spanning_Tree.cpp ├── LinearSearch.cpp ├── Maximum_Flow_Problem_I_Edmond_Karp.cpp ├── Merge_Sort.cpp ├── Minimum_expression.cpp ├── Pancake_sort.cpp ├── Power.cpp ├── Prim’s_Algorithm.cpp ├── Quick_Sort.cpp ├── Radix_Sort.cpp ├── Selection_Sort.cpp ├── TernarySearch.cpp ├── Trie.cpp ├── articulation_point.cpp ├── bellman_fords.cpp ├── berenstain_hashing.cpp ├── bfs.cpp ├── big_integer.cpp ├── binary_search.cpp ├── bipartite_graph_check.cpp ├── bridge.cpp ├── coin_change.cpp ├── computational_geometry_template.cpp ├── convex_hull_graham_scan.cpp ├── convex_hull_jarvis.cpp ├── dearrangement.cpp ├── dijkstra.cpp ├── double_hashing.cpp ├── doubly_linked_list.cpp ├── edit_distance.cpp ├── extended_euclid.cpp ├── factorial.cpp ├── floyd_cycle_finding.cpp ├── floyd_warshall.cpp ├── game_tree.cpp ├── grundy.cpp ├── hackenbush.cpp ├── hashmap.cpp ├── hashset.cpp ├── hashtable.cpp ├── heap.cpp ├── heap_sort.cpp ├── kadane.cpp ├── kmp.cpp ├── knapsack.cpp ├── kruskal.cpp ├── lca.cpp ├── lcp.cpp ├── lis.cpp ├── list.cpp ├── lps.cpp ├── map_hashing.cpp ├── matrix_exp.cpp ├── max_flow.cpp ├── maximum_bipartite_matching.cpp ├── maximum_sum_subarray.cpp ├── mcm.cpp ├── min_cost_path.cpp ├── min_vertex_cover.cpp ├── ncr.cpp ├── nim.cpp ├── nqueen.cpp ├── optimal_search_tree.cpp ├── permutation_generator.cpp ├── phi.cpp ├── primality_test.cpp ├── prime.cpp ├── prime_ring.cpp ├── queue.cpp ├── rabin_karp.cpp ├── scc.cpp ├── segment_tree.cpp ├── segment_tree_lazy.cpp ├── singly_linked_list.cpp ├── splay.cpp ├── stable_marriage_problem.cpp ├── stack.cpp ├── subset_sum.cpp ├── suffix_automata.cpp ├── suffix_lcp.cpp ├── ternary_search_tree.cpp ├── topsort.cpp ├── tsp.cpp ├── union_find.cpp ├── vector.cpp └── z.cpp /Function/Function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | // Algorithm function in STL 3 | //min : Tim so nho hon trong 2 so hoac nhieu so 4 | //max : Tim so lon hon trong 2 so hoac nhieu so 5 | int main1(){ 6 | cout << min(10,20) << " " << max(10,20) << endl; 7 | cout << min({1,2,3,4}) << " " << max({1,2,3,4}) << endl; 8 | } 9 | //min_element : Tim so nho nhat trong arr hoac vector 10 | //max_element : Tim so nho nhat trong arr hoac vector 11 | int main2(){ 12 | int a[5]={1,2,3,4,5}; 13 | cout << *min_element(a,a+5)<< endl; 14 | cout << *max_element(a,a+5)<< endl; 15 | vector b ={1,2,3,4,5}; 16 | cout << *min_element(begin(b),end(b)); 17 | cout << *max_element(begin(b),end(b)); 18 | } 19 | //accumulate : Tinh tong cac phan tu trong mang hoac mot vecto 20 | int main3(){ 21 | itn a[5]= {1,2,3,4,5}; 22 | int sum = accumulate(a,a+5,0); // a+x ; a+y+1: Tinh tong tu chi so x toi chi so y 23 | vector b= {1,2,3,4,5}; 24 | cout << accumulate(begin(b),end(b),0) // n.begin()+x, b.begin()+y+1 25 | } 26 | //swap : Hoan doi gia tri cua 2 bien 27 | int main4(){ 28 | int x=100; y=200; 29 | swap(x,y); 30 | } 31 | //sort : Sap xep cac phan tu tang dan hoac giam dan hoac theo 1 y nao do 32 | int main5(){ 33 | int a[5]={1,3,4,5,2}; 34 | sort(a,a+5,greater()); // a+x,a+y+1; 35 | vector b ={1,4,3,2,5}; 36 | sort(begin(b),end(b),greater()); 37 | // greater() co them ham nay thi sap xep theo thu tu giam dan 38 | string s[5] = {"a","b","c","r","1"}; 39 | sort(s,s+5); // sap xep theo thu tu tang dan theo tu dien giam dan 40 | } 41 | //stable_sort: Mang co nhieu phan tu cung gia tri va sap xep va on dinh truoc sau 42 | int main6(){ 43 | int a[6] = {-1,3,1,-1,-2,-3}; 44 | stable_sort(a,a+6,cmp); 45 | } 46 | //find : Tim kiem 1 phan tu nao do trong arr hoac vector va tra ve con tro den 47 | //phan tu no tim thay hoac khong thay thi toi vi tri con tro cuoi cung 48 | int main7(){ 49 | int a[5]={1,2,1,3,4}; 50 | auto it = find(a,a+5,3); 51 | if(it == a+5) cout << " FOUND"; 52 | else cout << " NOT FOUND"; 53 | vector b ={1,2,1,3,5}; 54 | auto it = find(b.begin(),b.end(),5); 55 | if(it==b.end()) cout << "NOT FOUND"; 56 | else cout << "FOUND"; 57 | } 58 | // Ap dung cho mang chua co thu tu 59 | //binary_search : Ap dung cho arr hoac vector da duoc sap xep tang hoac giam 60 | int main8(){ 61 | int a[5] = {1,2,3,4,5}; 62 | if(binary_search(a,a+5,2)) cout << "FOUND"; 63 | 64 | vector b = {1,2,3,4,5}; 65 | if(binary_search(begin(b),end(b),2)) cout << "FOUND"; 66 | } 67 | //lower_bound : Ap dung cho arr hoac vector da duoc sap xep va ap dung cho set va map 68 | // Tra ve con tro tai phan tu dau tien lon hon hoac bang x 69 | // >=x 70 | int main9(){ 71 | int a[6]={1,1,2,2,3,5}; 72 | auto it = lower_bound(a,a+6,2); 73 | cout << *it << endl; // Gia tri cua phan tu thoa man 74 | cout << it-a << endl; // Tra ve chi so cua gia tri thoa man 75 | 76 | vector b={1,1,2,2,3,4}; 77 | auto it = lower_bound(begin(b),end(b),2); 78 | cout << *it << endl; 79 | ciut << it - begin(b) << endl; 80 | } 81 | //upper_bound : Ap dung cho arr hoac vector da duoc sap xep va ap dung cho set va map 82 | // Tra ve con tro tai phan tu dau tien lon hon x 83 | // >x 84 | int main10(){ 85 | int a[6]={1,1,2,2,3,5}; 86 | auto it = upper(a,a+6,2); 87 | cout << *it << endl; // Gia tri cua phan tu thoa man 88 | cout << it-a << endl; // Tra ve chi so cua gia tri thoa man 89 | 90 | vector b={1,1,2,2,3,4}; 91 | auto it = upper(begin(b),end(b),2); 92 | cout << *it << endl; 93 | ciut << it - begin(b) << endl; 94 | } 95 | //memset : Co mot array a muon gan tat ca phan tu cua mang la 0 hoac -1 96 | int main11(){ 97 | int a[6]={1,1,2,2,3,5}; 98 | memset(a,0,sizeof(a)); 99 | } 100 | //fill : Gan cac phan tu trong array hoac vector 1 gia tri nao do 101 | int main12(){ 102 | int a[6]={1,1,2,2,3,5}; 103 | fill(a,a+6,1000); 104 | 105 | vector b={1,1,2,2,3,4}; 106 | fill(a.begin(),a.end(),1000); 107 | } 108 | //merge : Tron 2 array hoac 2 vector lai voi nhau trong truowng hop sap xep tang dan 109 | int main12(){ 110 | vector b={1,1,2,2,3,4}; 111 | vector a={1,4,6,7,20}; 112 | vector res(11); 113 | merge(a.begin(),a.end(),b.begin(),b.end(),res.begin()); 114 | } 115 | //reverse : De lat nguoc 1 array hoac 1 vector hoac 1 string 116 | int main13(){ 117 | int a[5]={!,2,3,4,5}; 118 | reverse(a,a+5); 119 | string s= "khiem"; 120 | reverse(begin(s),end(s)); 121 | } 122 | //LUU Y: 4 thuat toan set truoc khi su dung phai dung sort 123 | //set_union : Co 2 tap hop muon tim ra hop cua 2 tap do thi dung set_union 124 | int main14(){ 125 | int a[]={1,2,3,4,5}; 126 | int b[]={1,3,4,5,6,7}; 127 | vector u(11); 128 | auto it = set_union(a,a+5,b,b+6,u.begin()); 129 | u.resize(it - u.begin()); 130 | } 131 | //set_intersection : Co 2 tap hop muon tim ra giao cua 2 tap hop 132 | int main15(){ 133 | int a[]={1,2,3,4,5}; 134 | int b[]={1,3,4,5,6,7}; 135 | vector u(11); 136 | auto it = set_intersection(a,a+5,b,b+6,u.begin()); 137 | u.resize(it - u.begin()); 138 | } 139 | //set_diffenrence: Lay ra phan tu thuoc mang a ma khong thuoc mang b 140 | int main16(){ 141 | int a[]={0,2,3,4,8}; 142 | int b[]={1,3,4,5,6,7}; 143 | vector u(11); 144 | auto it = set_diffenrence(a,a+5,b,b+6,u.begin()); 145 | u.resize(it - u.begin()); 146 | } 147 | //set_symmetric_difference : Lay phan tu khong phai giao cua 2 tap hop 148 | int main14(){ 149 | int a[]={0,2,3,4,8}; 150 | int b[]={1,3,4,5,6,7}; 151 | vector u(11); 152 | auto it = set_symmetric_difference(a,a+5,b,b+6,u.begin()); 153 | u.resize(it - u.begin()); 154 | } -------------------------------------------------------------------------------- /Uses/deque.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //stack LIFO 4 | //queue FIFO 5 | //deque double end queue 6 | //size : Co bao nhieu phan tu 7 | //push_front(): Day vao dau 8 | //push_back() : Day vao cuoi 9 | //pop_front() : Xoa 1 pt o dau 10 | //pop_back(): Xoa 1 pt o cuoi 11 | //empty(): Check xem deque rong khon 12 | //front() : Lay ra phan tu o dau 13 | //back() : Lay ra phan tu o cuoi 14 | using namespace std; 15 | int main(){ 16 | deque q; 17 | q.push_front(2); 18 | q.push_back(3); 19 | q.push_back(4); 20 | q.push_back(5); 21 | q.push_front(1); 22 | q.pop_front(); 23 | cout << q.front() << q.back() << endl; 24 | q.pop_back(); 25 | cout << q.back(); 26 | } -------------------------------------------------------------------------------- /Uses/map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // map m; 4 | // size() : So luong phan tu cua map 5 | // Nhap phan tu vao map dung for each, iterator, insert, pair 6 | //first : key 7 | // second : value 8 | // map 9 | // find: Thong qua tim kiem key 10 | // count : Tim key 11 | int main(){ 12 | map mp; 13 | int n; cin >> n; 14 | for (int i = 0; i < n; i++) 15 | { 16 | int x; cin >> x; 17 | mp[x]++; 18 | } 19 | 20 | mp[100] =200; //(100,200) 21 | mp[200]= 300; //(200,300) 22 | mp.insert({300,400}); 23 | mp.insert({400,500}); 24 | cout << mp.size() << endl; 25 | for(auto x:mp){ 26 | cout << x.first << " " << x.second << endl; 27 | } 28 | for(map::iterator it = mp.begin();it !=mp.end; it++){ 29 | cout << *it.first << " " << *it.second << endl; 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Uses/pair.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // pair dung de luu cac cap so 4 | // pair p; 5 | // p.first : datatype1 6 | // p.second : datatype2 7 | //make_pair(100,200) : Tao pair co 2 gia tri 8 | //{100,200} : Tao pair co 2 gia tri 9 | //tuple< datatype1 , ...., datatype n> t : Khai bao ham tuple 10 | // Khoi tao ham tuple bang make_tuple hoac {} 11 | 12 | int main(){ 13 | pair p1 = make_pair(100,200); 14 | pair p2; 15 | pair p3; 16 | cout << p1.first << p1.second << endl; 17 | pair,int> v; // Khai bao 3 bien gia tri pair long nhau 18 | // De su dung nhieu phan tu cung 1 luc 19 | // vi du khai bao 3 gia tri ta su dung tuple 20 | tuple< int, int, int> t{1,2,3}; 21 | tuple< int, int, int> tmake_tuple(1,2,3); 22 | cout << get<0>(t) << endl; // truy cap gia tri thu 1 cua ham tuple 23 | 24 | return 0; 25 | } -------------------------------------------------------------------------------- /Uses/priority_queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | //priority_queue : Luon duy tri mot thu tu sao cho phan tu o top queue 5 | //luon la so lon nhat hoac nho nhat 6 | //push : day 1 pt vao pq 7 | //size : So luong gia tri 8 | // empty : Check rong hay khon 9 | //pop : Xoa phan tu o dau 10 | //top : Lay ra phan tu o dau, mac dinh la lon nhat 11 | // 12 | int main(){ 13 | priority_queue pq; // Khai bao hang doi uu tien mac dinh lon nhat 14 | priority_queue,greater()> pq2; // Mac dinh la be nhat 15 | pq.push(1); 16 | pq.push(4); 17 | pq.push(3); 18 | pq.push(5); 19 | cout << pq.top() << endl; 20 | pq.pop(); 21 | cout << pq.top() << endl; // In ra value lon nhat 22 | } -------------------------------------------------------------------------------- /Uses/queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | //FIFO 4 | //push Day vao cuoi hang doi 5 | //pop Xoa gia tri dau hang doi 6 | //empty Check hang doi rong 7 | //size Do rong cua hang doi 8 | //front 9 | int main(){ 10 | queue q; 11 | q.push(1); 12 | q.push(2); // Them gia tri vao cuoi hang doi 13 | q.push(3); 14 | q.push(4); 15 | cout << q.front() << endl; // In ra gia tri tai dau hang doi 16 | q.pop(); // Xoa gia tri o dau hang doi 17 | } -------------------------------------------------------------------------------- /Uses/set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | //O(logn) 4 | //set s; 5 | //insert : Them gia tri vao set 6 | //Neu insert mot phan tu da co thi khong them nua 7 | //s.size(): Do rong cua set 8 | //s.find : tim phan tu dua vao chi so tu be den lon da sap xep day nhap vao theo thu tu tu be den lon 9 | // Neu dung find khong co gia tri do thi se tra ve begin 10 | // find(data) != s.end() thi co gia tri do con khong thi khong co gia tri do 11 | //count : Tim phan tu trong set 12 | //Erase : Xoa phan tu trong set 13 | // Order 14 | // multiset ten; : Dung multiset thi cac gia tri giong nhua van duoc lap lai 15 | 16 | // Cho mang co n phan tu va so nguyen k, doi voi moi day con lien tiep co chieu 17 | // dai k. In ra duoc phan tu lon nhat trong day con do 18 | // Input 10 3 19 | // 1 2 3 4 5 6 7 8 9 10 20 | // Output 21 | // 3 3 4 5 8 9 10 22 | // De giai bai nay thi nen dung multiset 23 | //unordered_set 24 | int unordered_set(){ 25 | unordered_set s; 26 | for (int i = 0; i < 10; i++) 27 | { 28 | s.insert(i); 29 | } 30 | for(auto x:s){ 31 | cout << x >> endl; 32 | } 33 | 34 | } 35 | int baitapms(){ 36 | int n,k; 37 | cin >> n >>k; 38 | int a[n]; 39 | for (int &x :a) 40 | { 41 | cin >> x; 42 | } 43 | multiset ms; 44 | for (int i = 0; i < k; i++) 45 | { 46 | ms.insert(a[i]); 47 | } 48 | for (int i = k; i < n; i++) 49 | { 50 | cout << *ms.rbegin() << " "; 51 | ms.erase(ms.find(a[i-k])); 52 | ms.insert(a[i]); 53 | } 54 | cout << *ms.rbegin() << " "<< endl; 55 | 56 | 57 | } 58 | int main2(){ 59 | multiset s1; 60 | s1.insert(100); 61 | s1.insert(200); 62 | s1.insert(300); 63 | s1.insert(100); 64 | cout << s1.size() << endl; 65 | for(int x:s1){ 66 | cout << x << endl; 67 | } 68 | // Chu y neu dung erase trong multiset thi no se xoa het nhung gia tri ma can xoa 69 | // Neu muon xoa 1 gia tri 1 trong 2 cai cung gia tri thi phai dung iterator 70 | 71 | } 72 | int main(){ 73 | int n; 74 | cin >> n; 75 | set s; 76 | for (int i = 0; i < n; i++) // Dung vong lap de insert gia tri vao set 77 | { 78 | int x; cin >> x; 79 | s.insert(x); 80 | } 81 | 82 | for (int i = 0; i < 10; i++) 83 | { 84 | s.insert(i); 85 | } 86 | s.erase(5); // Xoa gia tri 5 hoac xoa gia tri iterator 87 | for(int x: s){ // Dung for x de duyet set 88 | cout << x << endl; 89 | } 90 | return 0; 91 | } -------------------------------------------------------------------------------- /Uses/stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main(){ 5 | stack st; 6 | st.push(1); 7 | st.push(2); // Them gia tri vao stack 8 | st.push(3); 9 | cout << st.top()<< endl; // In ra gia tri tren cung 10 | st.pop() // Xoa gia tri tren cung 11 | cout << st.size() << endl; // Co cua stack 12 | st.empty(); // Check ham rong khong 13 | while(!st.empty){ 14 | cout << st.top(); // In ra tung gia tri cua stack 15 | st.pop(); 16 | } 17 | } -------------------------------------------------------------------------------- /Uses/vecto.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | //vector ten_vector 6 | //push_back() : Day mot phan tu vao vector 7 | //size() : Kich thuoc cua vector 8 | // v[i] : khai bao gia tri tai chi so vector 9 | //Duyet cac phan tu bang for each, iterator, auto 10 | 11 | int main(){ 12 | int n; vector v(n); // Khai bao vecto nhung da co n phan tu v[n] 13 | int a[n]; 14 | for (int i = 0; i < n; i++) 15 | { 16 | cin >> a[i];// Dung for de nhap phan tu vao vecto khi co n phan tu 17 | } 18 | vector v; // Khai bao vecto 19 | vector v(n,100); // Khai bao vector co n phan tu deu co gia tri la 100 20 | for (int i = 0; i < n; i++) 21 | { 22 | int x; cin >> x; 23 | v.push_back(x); // Dung for de nhap phan tu vao vecto khi khong co n phan tu 24 | } 25 | 26 | v.push_back(10); // Day phan tu 10 vao vector 27 | v.push_back(20); 28 | v.push_back(50); 29 | v.push_back(100); 30 | cout << v.size() << endl; // In ra do rong vector 31 | cout << v[0] << endl; // In ra gia tri chi so dau tien cua vector 32 | cout << v[v.size()-1] << " " << v.back() << endl; // In ra phan tu cuoi cung cua vector 33 | for(int i=0; i < v.size();i++){ // Duyet bang for thuong 34 | cout << v[i] << endl; 35 | } 36 | for(int x:v){ // Duyet bang x 37 | cout << x << endl; 38 | } 39 | for(vector :: iterator it = v.begin(); it !=v.end();++it){ 40 | //Lap bang toan tu iterator 41 | cout << *it << endl; 42 | } 43 | for(auto it = v.begin(); it !=v.end();++it){ 44 | //Lap bang auto 45 | cout << *it << endl; 46 | } 47 | cout << v[2] << " " << *(v.begin()+2) << endl; // Dua ra gia tri tai chi so 48 | 49 | return 0; 50 | } 51 | 52 | // Tach cac tu bang vector 53 | 54 | int main1(){ 55 | string s=" Hoang manh khiem"; 56 | stringstream ss(s); // truy xuat du lieu 57 | string tmp; 58 | vector vt; 59 | while(ss>> tmp){ 60 | vt.push_back(tmp); 61 | } 62 | for(string x:vt){ 63 | cout << x<< endl; 64 | } 65 | } -------------------------------------------------------------------------------- /algorithms/2D_BIT.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class _2DBIT { 3 | public: 4 | T** tree; 5 | int MaxX, MaxY; 6 | 7 | _2DBIT(int M, int N) { 8 | *tree = new T*[M + 1]; 9 | for(int i = 0; i <= M; ++i) 10 | tree[i] = new T[N + 1]; 11 | memset(tree, 0, sizeof(T) * (M + 1) * (N + 1)); 12 | MaxX = M, MaxY = N; 13 | } 14 | ~_2DBIT() { 15 | free(tree); 16 | } 17 | 18 | void update(int x, int y, T val) { 19 | assert(x > 0 and y > 0); 20 | int y1; 21 | while(x <= MaxX) { 22 | y1 = y; 23 | while(y1 <= MaxY) { 24 | tree[x][y1] += val; 25 | y1 += (y1 & -y1); 26 | } 27 | x += (x & -x); 28 | } 29 | } 30 | 31 | T read(int x, int y) { 32 | assert(x > 0 and y > 0); 33 | int sum = 0, y1; 34 | while(x > 0) { 35 | y1 = y; 36 | while(y1 > 0) { 37 | sum += tree[x][y1]; 38 | y1 -= (y1 & -y1); 39 | } 40 | x -= (x & -x); 41 | } 42 | return sum; 43 | } 44 | }; -------------------------------------------------------------------------------- /algorithms/2D_segment_tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Usage: 3 | Segtree2d TMax; 4 | Segtree2dMin TMin; 5 | TMax.clear(Row, Col); 6 | TMax.update(x, y, value); 7 | TMax.query(x1, y1, x2, y2); 8 | */ 9 | int P[Max][Max]; 10 | 11 | struct Point { 12 | int x, y, mx; 13 | Point() {} 14 | Point(int x, int y, int mx) : x(x), y(y), mx(mx) { } 15 | 16 | bool operator < (const Point& other) const { 17 | return mx < other.mx; 18 | } 19 | }; 20 | 21 | struct Segtree2d { 22 | Point T[2 * Max * Max]; // assumed, not accurate 23 | int n, m; 24 | 25 | void clear(int n, int m) { 26 | this -> n = n; 27 | this -> m = m; 28 | build(1, 1, 1, n, m); 29 | } 30 | 31 | Point build(int node, int a1, int b1, int a2, int b2) { 32 | if (a1 > a2 or b1 > b2) 33 | return def(); 34 | 35 | if (a1 == a2 and b1 == b2) 36 | return T[node] = Point(a1, b1, P[a1][b1]); 37 | 38 | T[node] = def(); 39 | T[node] = maxNode(T[node], build(4 * node - 2, a1, b1, (a1 + a2) / 2, (b1 + b2) / 2 ) ); 40 | T[node] = maxNode(T[node], build(4 * node - 1, (a1 + a2) / 2 + 1, b1, a2, (b1 + b2) / 2 )); 41 | T[node] = maxNode(T[node], build(4 * node + 0, a1, (b1 + b2) / 2 + 1, (a1 + a2) / 2, b2) ); 42 | T[node] = maxNode(T[node], build(4 * node + 1, (a1 + a2) / 2 + 1, (b1 + b2) / 2 + 1, a2, b2) ); 43 | return T[node]; 44 | } 45 | 46 | Point query(int node, int a1, int b1, int a2, int b2, int x1, int y1, int x2, int y2) { 47 | if (x1 > a2 or y1 > b2 or x2 < a1 or y2 < b1 or a1 > a2 or b1 > b2) 48 | return def(); 49 | 50 | if (x1 <= a1 and y1 <= b1 and a2 <= x2 and b2 <= y2) 51 | return T[node]; 52 | 53 | Point mx = def(); 54 | mx = maxNode(mx, query(4 * node - 2, a1, b1, (a1 + a2) / 2, (b1 + b2) / 2, x1, y1, x2, y2) ); 55 | mx = maxNode(mx, query(4 * node - 1, (a1 + a2) / 2 + 1, b1, a2, (b1 + b2) / 2, x1, y1, x2, y2) ); 56 | mx = maxNode(mx, query(4 * node + 0, a1, (b1 + b2) / 2 + 1, (a1 + a2) / 2, b2, x1, y1, x2, y2) ); 57 | mx = maxNode(mx, query(4 * node + 1, (a1 + a2) / 2 + 1, (b1 + b2) / 2 + 1, a2, b2, x1, y1, x2, y2)); 58 | 59 | return mx; 60 | } 61 | 62 | Point query(int x1, int y1, int x2, int y2) { 63 | return query(1, 1, 1, n, m, x1, y1, x2, y2); 64 | } 65 | 66 | Point update(int node, int a1, int b1, int a2, int b2, int x, int y, int value) { 67 | if (a1 > a2 or b1 > b2) 68 | return def(); 69 | 70 | if (x > a2 or y > b2 or x < a1 or y < b1) 71 | return T[node]; 72 | 73 | if (x == a1 and y == b1 and x == a2 and y == b2) 74 | return T[node] = Point(x, y, value); 75 | 76 | Point mx = def(); 77 | 78 | mx = maxNode(mx, update(4 * node - 2, a1, b1, (a1 + a2) / 2, (b1 + b2) / 2, x, y, value) ); 79 | mx = maxNode(mx, update(4 * node - 1, (a1 + a2) / 2 + 1, b1, a2, (b1 + b2) / 2, x, y, value)); 80 | mx = maxNode(mx, update(4 * node + 0, a1, (b1 + b2) / 2 + 1, (a1 + a2) / 2, b2, x, y, value)); 81 | mx = maxNode(mx, update(4 * node + 1, (a1 + a2) / 2 + 1, (b1 + b2) / 2 + 1, a2, b2, x, y, value) ); 82 | 83 | return T[node] = mx; 84 | } 85 | 86 | Point update(int x, int y, int value) { 87 | return update(1, 1, 1, n, m, x, y, value); 88 | } 89 | 90 | // utility functions; these functions are virtual because they will be overridden in child class 91 | virtual Point maxNode(Point a, Point b) { 92 | return max(a, b); 93 | } 94 | 95 | virtual Point def() { 96 | return Point(0, 0, -INF); 97 | } 98 | }; 99 | 100 | struct Segtree2dMin : Segtree2d { 101 | Point maxNode(Point a, Point b) { 102 | return min(a, b); 103 | } 104 | 105 | Point def() { 106 | return Point(0, 0, INF); 107 | } 108 | }; -------------------------------------------------------------------------------- /algorithms/Aho_Corasick.cpp: -------------------------------------------------------------------------------- 1 | // Aho-Corasick Algorithm 2 | // like unix fgrep - applicable when there are multiple patterns 3 | // O(m + n + z) where m is total length of patterns, n is text length and z is number of occurance 4 | // Max number of states in the matching machine. 5 | // Should be equal to the sum of the length of all keywords. 6 | const int MAX_STATE = 500; 7 | 8 | const int MAX_CHAR = 26; // 256 9 | 10 | // Bit i in this mask is one if the word with index i 11 | // appears when the machine enters this state. 12 | int output[MAX_STATE]; 13 | 14 | int failure[MAX_STATE]; 15 | 16 | int trie[MAX_STATE][MAX_CHAR]; 17 | 18 | // Builds the string matching machine. 19 | // arr - array of words. The index of each keyword is important: 20 | // "out[state] & (1 << i)" is > 0 if we just found word[i] 21 | // in the text. 22 | // Returns the number of states that the built machine has. 23 | // States are numbered 0 up to the return value - 1, inclusive. 24 | int buildMatchingMachine(vector& pattern) 25 | { 26 | int n = (int)pattern.size(); 27 | // Initialize all values in output function as 0. 28 | memset(output, 0, sizeof output); 29 | 30 | // Initialize all values in goto function as -1. 31 | memset(trie, -1, sizeof trie); 32 | 33 | // Initially, we just have the 0 state 34 | int states = 1; 35 | 36 | // ##### Build Trie ####### 37 | 38 | for (int i = 0; i < n; ++i) { 39 | const string& word = pattern[i]; 40 | int currentState = 0; 41 | 42 | for (int j = 0; j < word.size(); ++j) { 43 | int ch = word[j] - 'a'; 44 | if (trie[currentState][ch] == -1) { 45 | trie[currentState][ch] = states++; 46 | } 47 | currentState = trie[currentState][ch]; 48 | } 49 | 50 | output[currentState] |= (1 << i); 51 | } 52 | 53 | // For all characters which don't have an edge from 54 | // root (or state 0) in Trie, add a goto edge to state 55 | // 0 itself 56 | for (int ch = 0; ch < MAX_CHAR; ++ch) { 57 | if(trie[0][ch] == -1) { 58 | trie[0][ch] = 0; 59 | } 60 | } 61 | 62 | // ##### Build Failure function ####### 63 | 64 | // Initialize values in fail function 65 | memset(failure, -1, sizeof failure); 66 | 67 | // Failure function is computed in breadth first order 68 | // using a queue 69 | queue q; 70 | 71 | // Iterate over every possible input 72 | for (int ch = 0; ch < MAX_CHAR; ++ch) { 73 | // All nodes of depth 1 have failure function value 74 | if (trie[0][ch] != 0) { 75 | failure[trie[0][ch]] = 0; 76 | q.push(trie[0][ch]); 77 | } 78 | } 79 | 80 | // Noe queue contains all nodes of depth 1 81 | while (q.size()) { 82 | int state = q.front(); 83 | q.pop(); 84 | 85 | // For the removed state, find failure function for 86 | // all those characters for which goto function is defined. 87 | for (int ch = 0; ch <= MAX_CHAR; ++ch) { 88 | // If goto function is defined for character 'ch' and 'state' 89 | if (trie[state][ch] != -1) { 90 | // Find failure state of removed state 91 | int f = failure[state]; 92 | 93 | // Find the deepest node labeled by proper 94 | // suffix of string from root to current 95 | // state. 96 | while (trie[f][ch] == -1) { 97 | f = failure[f]; 98 | } 99 | 100 | f = trie[f][ch]; 101 | failure[trie[state][ch]] = f; 102 | 103 | // Merge output values 104 | output[trie[state][ch]] |= output[f]; 105 | 106 | // Insert the next level node (of Trie) in Queue 107 | q.push(trie[state][ch]); 108 | } 109 | } 110 | } 111 | 112 | return states; 113 | } 114 | 115 | // Returns the next state the machine will transition to using goto and failure functions. 116 | // currentState - The current state of the machine. Must be between 0 and the number of states - 1, inclusive. 117 | // nextInput - The next character that enters into the machine. 118 | int findNextState(int currentState, char nextInput) { 119 | int answer = currentState; 120 | int ch = nextInput - 'a'; 121 | 122 | // If goto is not defined, use failure function 123 | while (trie[answer][ch] == -1) { 124 | answer = failure[answer]; 125 | } 126 | 127 | return trie[answer][ch]; 128 | } 129 | 130 | // This function finds all occurrences of all array words 131 | // in text. 132 | void searchWords(vector& pattern, string text) { 133 | int n = (int)pattern.size(); 134 | // Preprocess patterns. 135 | // Build machine with goto, failure and output functions 136 | buildMatchingMachine(pattern); 137 | 138 | // Initialize current state 139 | int currentState = 0; 140 | 141 | // Traverse the text through the nuilt machine to find 142 | // all occurrences of words in arr[] 143 | for (int i = 0; i < text.size(); ++i) { 144 | currentState = findNextState(currentState, text[i]); 145 | 146 | // If match not found, move to next state 147 | if (output[currentState] == 0) continue; 148 | 149 | // Match found, print all matching words of arr[] 150 | // using output function. 151 | for (int j = 0; j < n; ++j) { 152 | if (output[currentState] & (1 << j)) { 153 | cout << "Word " << pattern[j] << " appears from " << i - pattern[j].size() + 1 << " to " << i << endl; 154 | } 155 | } 156 | } 157 | } 158 | 159 | /* 160 | vector pattern{"he", "she", "his", "hers"}; 161 | string text = "ahishers"; 162 | searchWords(pattern, text); 163 | */ -------------------------------------------------------------------------------- /algorithms/BIT.cpp: -------------------------------------------------------------------------------- 1 | // Intuition behind BIT: http://stackoverflow.com/a/15444954/1162233 2 | template 3 | class BIT { 4 | public: 5 | T *tree; 6 | int MaxVal; // maximum value which will have non-zero frequency 7 | 8 | BIT(int N) { 9 | tree = new T[N + 1]; 10 | memset(tree, 0, sizeof(T) * (N + 1)); 11 | MaxVal = N; 12 | } 13 | 14 | ~BIT() { 15 | free(tree); 16 | } 17 | 18 | // O(MaxVal logMaxVal) 19 | void build(int* data) { 20 | for(int i = 1; i <= MaxVal; ++i) { // O(MaxVal) 21 | int idx = i; 22 | while(idx <= MaxVal) { // O(log MaxVal) 23 | tree[idx] += data[i]; 24 | idx += (idx & -idx); 25 | } 26 | } 27 | } 28 | 29 | // Time: O(log maxVal) 30 | void update(int idx, T val) { 31 | assert(idx > 0); 32 | while (idx <= MaxVal) { 33 | tree[idx] += val; 34 | idx += (idx & -idx); 35 | } 36 | } 37 | //Returns the cumulative frequency of index idx 38 | // Time: O(log maxVal) 39 | T read(int idx) { 40 | assert(idx > 0); 41 | T sum = 0; 42 | while (idx > 0) { 43 | sum += tree[idx]; 44 | idx -= (idx & -idx); 45 | } 46 | return sum; 47 | } 48 | 49 | // Time: c * O(log maxVal); where c is a constant less than 1 50 | T readSingle(int idx) { 51 | assert(idx > 0); 52 | T sum = tree[idx]; 53 | if(idx == 0) return sum; 54 | 55 | int z = idx - (idx & -idx); 56 | int y = idx - 1; // y is predeccesor of x 57 | while(y != z) { 58 | sum -= tree[y]; 59 | y -= (y & -y); 60 | } 61 | return sum; 62 | } 63 | 64 | // Time: O(maxVal) 65 | void scale(T factor) { 66 | for(int i = 1; i <= MaxVal; ++i) { 67 | tree[i] /= factor; // scale-down 68 | // tree[i] *= factor; // scale-up 69 | } 70 | } 71 | 72 | // if in tree exists more than one index with a same 73 | // cumulative frequency, this procedure will return 74 | // some of them (we do not know which one) 75 | 76 | // bitMask - initialy, it is the greatest bit of MaxVal 77 | // bitMask store interval which should be searched 78 | int find(T cumFre) { 79 | int idx = 0; // this var is result of function 80 | int bitMask = (1 << (int) floor(log((double) MaxVal) / log(2.0))); 81 | 82 | while((bitMask != 0) and (idx < MaxVal)) { // nobody likes overflow :) 83 | int tIdx = idx + bitMask; // we make midpoint of interval 84 | if (cumFre == tree[tIdx]) // if it is equal, we just return idx 85 | return tIdx; 86 | else if (cumFre > tree[tIdx]) { 87 | // if tree frequency "can fit" into cumFre, 88 | // then include it 89 | idx = tIdx; // update index 90 | cumFre -= tree[tIdx]; // set frequency for next loop 91 | } 92 | bitMask >>= 1; // half current interval 93 | } 94 | if (cumFre != 0) // maybe given cumulative frequency doesn't exist 95 | return -1; 96 | else 97 | return idx; 98 | } 99 | 100 | }; -------------------------------------------------------------------------------- /algorithms/BinarySearch.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to implement recursive Binary Search 2 | #include 3 | using namespace std; 4 | 5 | // A recursive binary search function. It returns 6 | // location of x in given array arr[l..r] is present, 7 | // otherwise -1 8 | int binarySearch(int arr[], int l, int r, int x) 9 | { 10 | if (r >= l) { 11 | int mid = l + (r - l) / 2; 12 | 13 | // If the element is present at the middle 14 | // itself 15 | if (arr[mid] == x) 16 | return mid; 17 | 18 | // If element is smaller than mid, then 19 | // it can only be present in left subarray 20 | if (arr[mid] > x) 21 | return binarySearch(arr, l, mid - 1, x); 22 | 23 | // Else the element can only be present 24 | // in right subarray 25 | return binarySearch(arr, mid + 1, r, x); 26 | } 27 | 28 | // We reach here when element is not 29 | // present in array 30 | return -1; 31 | } 32 | // Chỉ tìm được chỉ số cho hàm nhập vào cho quy luật tăng dần hoặc giảm dần. 33 | int main(void) 34 | { 35 | int n,x,i; 36 | cin >> n; 37 | int arr[n]; 38 | for (i = 0; i < n; i++) cin >> arr[i]; 39 | cin >> x; 40 | int result = binarySearch(arr, 0, n - 1, x); 41 | (result == -1) 42 | ? cout << "Element is not present in array" 43 | : cout << "Element is present at index " << result; 44 | return 0; 45 | } -------------------------------------------------------------------------------- /algorithms/Bubble_Sort.cpp: -------------------------------------------------------------------------------- 1 | // O(n^2) 2 | for(int i = 0; i < n - 1; ++i) 3 | for(int j = 0, m = n - i - 1; j < m; ++j) 4 | if(arr[j] > arr[j + 1]) 5 | swap(arr[j], arr[j + 1]); -------------------------------------------------------------------------------- /algorithms/Bucket_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | usage: i.e. Sort a large set of floating point numbers which are in range from 0.0 to 1.0 3 | and are uniformly distributed across the range 4 | */ 5 | void bucketSort(float* arr, int n) { 6 | // 1) Create n empty buckets - O(n) 7 | vector b[n]; 8 | 9 | // 2) Put array elements in different buckets - O(n) 10 | for (int i = 0; i < n; i++) { 11 | int bi = n * arr[i]; // Index in bucket 12 | b[bi].push_back(arr[i]); 13 | } 14 | 15 | // 3) Sort individual buckets - O(n) 16 | for (int i = 0; i < n; i++) 17 | sort(b[i].begin(), b[i].end()); 18 | 19 | // 4) Concatenate all buckets into arr[] - O(n) 20 | int index = 0; 21 | for (int i = 0; i < n; i++) 22 | for (int j = 0; j < b[i].size(); j++) 23 | arr[index++] = b[i][j]; 24 | } -------------------------------------------------------------------------------- /algorithms/CatalanNumber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define MAX 1000 4 | 5 | class CatalanNumber { 6 | public: 7 | int dp[MAX]; 8 | 9 | void catalanNumber(int n) { 10 | dp[0] = dp[1] = 1; 11 | 12 | for(int k = 2; k <= n; ++k) { 13 | for(int i = 1; i <= k; ++i) { 14 | dp[k] += dp[i - 1] * dp[k - i]; 15 | } 16 | } 17 | 18 | } 19 | }; 20 | 21 | int main() { 22 | } -------------------------------------------------------------------------------- /algorithms/Count_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time: O(n + k); k = range of input 3 | Auxiliary space: O(n + k) 4 | */ 5 | void countSort(string& str) { 6 | // The output character array that will have sorted str 7 | char output[(int)str.length()]; 8 | 9 | // Create a count array to store count of inidividul characters and 10 | // initialize count array as 0 11 | int count[RANGE + 1] = {0}; 12 | 13 | // Store count of each character 14 | for(int i = 0; i < (int)str.length(); ++i) 15 | ++count[str[i]]; 16 | 17 | // Change count[i] so that count[i] now contains actual position of 18 | // this character in output array 19 | for (int i = 1; i <= RANGE; ++i) 20 | count[i] += count[i - 1]; 21 | 22 | // Build the output character array 23 | for (int i = 0; i < (int)str.length(); ++i) { 24 | output[count[str[i]] - 1] = str[i]; 25 | --count[str[i]]; 26 | } 27 | 28 | // Copy the output array to str, so that str now 29 | // contains sorted characters 30 | for(int i = 0; i < (int)str.length(); ++i) 31 | str[i] = output[i]; 32 | } -------------------------------------------------------------------------------- /algorithms/DAG_min_path.cpp: -------------------------------------------------------------------------------- 1 | // Find minimum cost path from top-left corner to any bottom cell 2 | int call(int i, int j) { 3 | if(isValid(i, j)) { //if still inside the array 4 | if(dp[i][j] != -1) return dp[i][j]; 5 | int ret = INT_MIN; 6 | //try to move to 3 direction, also add current cell's point 7 | ret = max(ret, call(i + 1, j) + mat[i][j]); 8 | ret = max(ret, call(i + 1, j - 1) + mat[i][j]); 9 | ret = max(ret, call(i + 1, j + 1) + mat[i][j]); 10 | return dp[i][j] = ret; 11 | } 12 | 13 | return 0; //if outside the array 14 | } -------------------------------------------------------------------------------- /algorithms/Digit_dp_I.cpp: -------------------------------------------------------------------------------- 1 | // Digit DP 2 | // Count how many numbers are there between A and B inclusive which sum of digits is equal to S 3 | #define BIT_LENGTH_32 32 4 | #define BIT_LENGTH_64 64 5 | #define MAX_SUM 200 6 | 7 | i64 dp[BIT_LENGTH_64][MAX_SUM]; 8 | bool visited[BIT_LENGTH_64][MAX_SUM]; 9 | i64 A, B; 10 | int S; 11 | 12 | i64 solveUtil(int depth, int sum) { 13 | if(depth == 0) { 14 | return (i64) (sum == 0); 15 | } 16 | if(visited[depth][sum]) { 17 | return dp[depth][sum]; 18 | } 19 | i64 ret = 0LL; 20 | for(int d = 0; d <= 9; ++d) { 21 | if(sum - d >= 0) { 22 | ret += solveUtil(depth - 1, sum - d); 23 | } 24 | } 25 | visited[depth][sum] = true; 26 | return dp[depth][sum] = ret; 27 | } 28 | 29 | i64 solve(i64 N) { 30 | if(N < 0LL) return 0LL; 31 | char buffer[BIT_LENGTH_64]; 32 | sprintf(buffer, LLD, N); 33 | int len = strlen(buffer); 34 | int sum = S; 35 | int depth = len; 36 | i64 ret = 0LL; 37 | for(int i = 0; i < len; ++i) { 38 | int digit = buffer[i] - '0'; 39 | for(int d = 0; d < digit; ++d) { 40 | if(sum - d >= 0) { 41 | ret += solveUtil(depth - 1, sum - d); 42 | } 43 | } 44 | depth--; 45 | sum -= digit; 46 | } 47 | ret += (sum == 0); 48 | return ret; 49 | } 50 | 51 | // solve(B) - solve(A - 1LL); 52 | 53 | -------------------------------------------------------------------------------- /algorithms/Digit_dp_II.cpp: -------------------------------------------------------------------------------- 1 | // Digit DP 2 | // Count how many numbers are there between A and B inclusive which sum of digits is divisble by K 3 | #define BIT_LENGTH_64 64 4 | #define MAX_REMAINDER 5 // can be 0, 1, 2 ... K - 1 only 5 | 6 | i64 dp[BIT_LENGTH_64][MAX_REMAINDER]; 7 | bool visited[BIT_LENGTH_64][MAX_REMAINDER]; 8 | i64 A, B; 9 | int K; // 5 10 | 11 | i64 solveUtil(int depth, int remainder) { 12 | if(depth == 0) { 13 | return (remainder == 0); 14 | } 15 | if(visited[depth][remainder]) { 16 | return dp[depth][remainder]; 17 | } 18 | i64 ret = 0LL; 19 | for(int d = 0; d <= 9; ++d) { 20 | ret += solveUtil(depth - 1, (remainder + d) % K); 21 | } 22 | visited[depth][remainder] = true; 23 | return dp[depth][remainder] = ret; 24 | } 25 | 26 | i64 solve(i64 N) { 27 | if(N < 0LL) return 0LL; 28 | char buffer[BIT_LENGTH_64]; 29 | sprintf(buffer, LLD, N); 30 | int len = (int)strlen(buffer); 31 | int remainder = 0; 32 | int depth = len; 33 | i64 ret = 0LL; 34 | for(int i = 0; i < len; ++i) { 35 | int digit = buffer[i] - '0'; 36 | for(int d = 0; d < digit; ++d) { 37 | ret += solveUtil(depth - 1, (remainder + d) % K); 38 | } 39 | depth--; 40 | remainder = (remainder + digit) % K; 41 | } 42 | ret += (remainder == 0); 43 | return ret; 44 | } 45 | 46 | // solve(B) - solve(A - 1LL) -------------------------------------------------------------------------------- /algorithms/Digit_dp_III.cpp: -------------------------------------------------------------------------------- 1 | // calculates number of substrings divisble by d 2 | int solve(string const& num, int d) { 3 | int ans = 0; 4 | int n = (int)num.length(); 5 | vector> dp(n, vector(d, 0)); // dp[i][j] = number of substrings ended at i with remainder j (mod d) 6 | for(int i = 0; i < n; i++) { 7 | int digit = num[i] - '0'; 8 | dp[i][digit % d]++; 9 | if(i > 0) { 10 | for(int j = 0; j < d; j++) { 11 | int r = (j * 10 + digit) % d; 12 | dp[i][r] += dp[i - 1][j]; 13 | } 14 | } 15 | ans += dp[i][0]; 16 | // if numbers with preceeding 0 aren't allowed except '0' itself 17 | /* 18 | if(digit == 0) { 19 | dp[i][digit % d]--; 20 | } 21 | */ 22 | } 23 | return ans; 24 | } 25 | 26 | /* 27 | solve("10888", 8) => 12 28 | */ -------------------------------------------------------------------------------- /algorithms/Digit_dp_IV.cpp: -------------------------------------------------------------------------------- 1 | // calculates number of subsequences divisble by d 2 | int solve(string const& num, int d) { 3 | int ans = 0; 4 | int n = (int)num.length(); 5 | vector> dp(n, vector(d, 0)); // dp[i][j] = number of subsequences ended at i with remainder j (mod d) 6 | for(int i = 0; i < n; i++) { 7 | int digit = num[i] - '0'; 8 | dp[i][digit % d]++; 9 | for(int j = 0; j < i; j++) { 10 | for(int k = 0; k < d; k++) { 11 | int r = (k * 10 + digit) % d; 12 | dp[i][r] += dp[j][k]; 13 | } 14 | } 15 | ans += dp[i][0]; 16 | // if numbers with preceeding 0 aren't allowed except '0' itself 17 | /* 18 | if(digit == 0) { 19 | dp[i][digit % d]--; 20 | } 21 | */ 22 | } 23 | return ans; 24 | } 25 | 26 | /* 27 | solve("10888", 8) => 20 28 | */ 29 | 30 | 31 | 32 | // Top-down approach 33 | 34 | int solveUtil(int indx, int mod, string const& num, int d, vector>& dp) { 35 | if(indx == (int)num.length()) { 36 | return (mod == 0); 37 | } 38 | if(dp[indx][mod] != -1) { 39 | return dp[indx][mod]; 40 | } 41 | int ret = 0; 42 | int digit = num[indx] - '0'; 43 | ret += solveUtil(indx + 1, (mod * 10 + digit) % d, num, d, dp); 44 | ret += solveUtil(indx + 1, mod, num, d, dp); 45 | 46 | return dp[indx][mod] = ret; 47 | } 48 | 49 | int solve(string const& num, int d) { 50 | int n = (int)num.length(); 51 | vector> dp(n, vector(d, -1)); 52 | return solveUtil(0, 0, num, d, dp); 53 | } 54 | 55 | /* 56 | solve("10888", 8) - 1 // minus 1 to exclude empty string counting 57 | */ -------------------------------------------------------------------------------- /algorithms/Dijkstra’s_Shortest_Path.cpp: -------------------------------------------------------------------------------- 1 | // C++ program for Dijkstra's single source shortest path 2 | // algorithm. The program is for adjacency matrix 3 | // representation of the graph 4 | #include 5 | using namespace std; 6 | #include 7 | 8 | // Number of vertices in the graph 9 | #define V 9 10 | 11 | // A utility function to find the vertex with minimum 12 | // distance value, from the set of vertices not yet included 13 | // in shortest path tree 14 | int minDistance(int dist[], bool sptSet[]) 15 | { 16 | 17 | // Initialize min value 18 | int min = INT_MAX, min_index; 19 | 20 | for (int v = 0; v < V; v++) 21 | if (sptSet[v] == false && dist[v] <= min) 22 | min = dist[v], min_index = v; 23 | 24 | return min_index; 25 | } 26 | 27 | // A utility function to print the constructed distance 28 | // array 29 | void printSolution(int dist[]) 30 | { 31 | cout << "Vertex \t Distance from Source" << endl; 32 | for (int i = 0; i < V; i++) 33 | cout << i << " \t\t\t\t" << dist[i] << endl; 34 | } 35 | 36 | // Function that implements Dijkstra's single source 37 | // shortest path algorithm for a graph represented using 38 | // adjacency matrix representation 39 | void dijkstra(int graph[V][V], int src) 40 | { 41 | int dist[V]; // The output array. dist[i] will hold the 42 | // shortest 43 | // distance from src to i 44 | 45 | bool sptSet[V]; // sptSet[i] will be true if vertex i is 46 | // included in shortest 47 | // path tree or shortest distance from src to i is 48 | // finalized 49 | 50 | // Initialize all distances as INFINITE and stpSet[] as 51 | // false 52 | for (int i = 0; i < V; i++) 53 | dist[i] = INT_MAX, sptSet[i] = false; 54 | 55 | // Distance of source vertex from itself is always 0 56 | dist[src] = 0; 57 | 58 | // Find shortest path for all vertices 59 | for (int count = 0; count < V - 1; count++) { 60 | // Pick the minimum distance vertex from the set of 61 | // vertices not yet processed. u is always equal to 62 | // src in the first iteration. 63 | int u = minDistance(dist, sptSet); 64 | 65 | // Mark the picked vertex as processed 66 | sptSet[u] = true; 67 | 68 | // Update dist value of the adjacent vertices of the 69 | // picked vertex. 70 | for (int v = 0; v < V; v++) 71 | 72 | // Update dist[v] only if is not in sptSet, 73 | // there is an edge from u to v, and total 74 | // weight of path from src to v through u is 75 | // smaller than current value of dist[v] 76 | if (!sptSet[v] && graph[u][v] 77 | && dist[u] != INT_MAX 78 | && dist[u] + graph[u][v] < dist[v]) 79 | dist[v] = dist[u] + graph[u][v]; 80 | } 81 | 82 | // print the constructed distance array 83 | printSolution(dist); 84 | } 85 | 86 | // driver's code 87 | int main() 88 | { 89 | 90 | /* Let us create the example graph discussed above */ 91 | int graph[V][V] = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 }, 92 | { 4, 0, 8, 0, 0, 0, 0, 11, 0 }, 93 | { 0, 8, 0, 7, 0, 4, 0, 0, 2 }, 94 | { 0, 0, 7, 0, 9, 14, 0, 0, 0 }, 95 | { 0, 0, 0, 9, 0, 10, 0, 0, 0 }, 96 | { 0, 0, 4, 14, 10, 0, 2, 0, 0 }, 97 | { 0, 0, 0, 0, 0, 2, 0, 1, 6 }, 98 | { 8, 11, 0, 0, 0, 0, 1, 0, 7 }, 99 | { 0, 0, 2, 0, 0, 0, 6, 7, 0 } }; 100 | 101 | // Function call 102 | dijkstra(graph, 0); 103 | 104 | return 0; 105 | } 106 | 107 | // This code is contributed by shivanisinghss2110 108 | -------------------------------------------------------------------------------- /algorithms/FFT.cpp: -------------------------------------------------------------------------------- 1 | class FFT { 2 | public: 3 | struct Point { 4 | double x, y; 5 | }; 6 | 7 | Point pointPlus(Point a, Point b) { 8 | a.x += b.x; 9 | a.y += b.y; 10 | return a; 11 | } 12 | 13 | Point pointMinus(Point a, Point b) { 14 | a.x -= b.x; 15 | a.y -= b.y; 16 | return a; 17 | } 18 | 19 | Point pointMultiple(Point a, Point b) { 20 | Point c; 21 | c.x = a.x * b.x - a.y * b.y; 22 | c.y = a.x * b.y + a.y * b.x; 23 | return c; 24 | } 25 | 26 | Point pointMultipleDouble(Point a, double k) { 27 | a.x *= k; 28 | a.y *= k; 29 | return a; 30 | } 31 | 32 | Point pointPolar(double r, double t) { 33 | Point a; 34 | a.x = r * cos(t); 35 | a.y = r * sin(t); 36 | return a; 37 | } /* r * exp(i * t), i = sqrt(-1) */ 38 | 39 | static Point pointGenerator(double x, double y) { 40 | Point res; 41 | res.x = x; 42 | res.y = y; 43 | return res; 44 | } /* x + i * y * 45 | 46 | /* Fast Fourier Transform */ 47 | /* n = size of a = a power of 2, theta = 2 * PI / n */ 48 | /* for inverse fft, theta = -2 * PI / n */ 49 | void calcDFT(int n, double theta, vector& a) { 50 | 51 | for(int m = n; m >= 2; m /= 2) { 52 | int mh = m / 2; 53 | rep(i, mh) { 54 | Point w = pointPolar(1, i * theta); 55 | for(int j = i; j < n; j += m) { 56 | int k = j + mh; 57 | Point x = pointMinus(a[j], a[k]); 58 | a[j] = pointPlus(a[j], a[k]); 59 | a[k] = pointMultiple(w, x); 60 | } 61 | } 62 | theta *= 2; 63 | } 64 | 65 | int i = 0; 66 | FOR(j, 1, n - 2) { 67 | for(int k = n / 2; k > (i ^= k); k /= 2); 68 | if(j < i) { 69 | Point tmp = a[i]; 70 | a[i] = a[j]; 71 | a[j] = tmp; 72 | } 73 | } 74 | } 75 | 76 | vector iDFT(int N, vector& P, vector& Q) { 77 | vector R(N, pointGenerator(0, 0)); 78 | double invN = 1.0 / N; 79 | double theta = 2 * PI * invN; 80 | 81 | // P and Q are polynomials of M (<= N / 2) degree 82 | // R is polynomial of N degree contains the multiplication result of P and Q 83 | calcDFT(N, theta, P); 84 | calcDFT(N, theta, Q); 85 | rep(i, N) { 86 | R[i] = pointMultiple(P[i], Q[i]); 87 | } 88 | calcDFT(N, -1.0 * theta, R); 89 | 90 | rep(i, N) { 91 | R[i].x *= invN; 92 | } 93 | 94 | return R; 95 | } 96 | }; 97 | 98 | /* 99 | Example: 100 | FFT fft; 101 | vector P(65536, FFT::pointGenerator(0, 0)), Q(65536, FFT::pointGenerator(0, 0)); 102 | P[0].x = 2, P[1].x = 3, P[2].x = 4; // 2 + 3x + 4x^2 103 | Q[0].x = 5, Q[1].x = 7; // 5 + 7x 104 | vector R = fft.iDFT(65536, P, Q); // 10 + 29x + 41x^2 + 28x^3 105 | 106 | */ 107 | -------------------------------------------------------------------------------- /algorithms/Finite_Automata_Pattern_Searching.cpp: -------------------------------------------------------------------------------- 1 | #define NO_OF_CHARS 256 2 | #define M 30 // number of characters in pattern 3 | int m, n; 4 | int TF[M][NO_OF_CHARS]; 5 | 6 | void computeTransFunc(string pattern) { 7 | for(int x = 0; x < NO_OF_CHARS; ++x) { 8 | TF[0][x] = 0; 9 | } 10 | TF[0][pattern[0]] = 1; 11 | 12 | for(int i = 1, LPS = 0; i <= m; ++i) { 13 | for(int x = 0; x < NO_OF_CHARS; ++x) { 14 | TF[i][x] = TF[LPS][x]; 15 | } 16 | TF[i][pattern[i]] = i + 1; 17 | 18 | if(i < m) { 19 | LPS = TF[LPS][pattern[i]]; 20 | } 21 | } 22 | } 23 | 24 | void search(string pattern, string txt) { 25 | m = pattern.length(); 26 | n = txt.length(); 27 | 28 | computeTransFunc(pattern); 29 | 30 | for(int i = 0, j = 0; i < n; ++i) { 31 | j = TF[j][txt[i]]; 32 | if(j == m) { 33 | printf ("pattern found at index %d\n", i - m + 1); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /algorithms/HLD.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | problem ID: QTREE (spoj) 3 | source: Anudeep's blog on HLD 4 | Time Complexity: O(log^2 n) 5 | */ 6 | #define root 0 7 | #define N 10100 8 | #define LogN 14 // log(N) 9 | #define segTreeSize 32768 // 2 * pow(2.0, floor(log((double) N ) / log(2.0)) + 1 10 | 11 | vector adj[N], costs[N], indexx[N]; 12 | int baseArray[N], ptr; 13 | int chainNo, chainInd[N], chainHead[N], posInBase[N]; 14 | int depth[N], table[N][LogN], otherEnd[N], subTreeSize[N]; 15 | int segment_tree[segTreeSize]; 16 | 17 | // See Segment Tree for Implementation 18 | 19 | void buildSegTree(int node = 1, int start = 0, int end = ptr - 1); 20 | 21 | void update(int node, int start, int end, int index, int value ); 22 | 23 | int querySegTree(int node, int start, int end, int i, int j); 24 | 25 | /* 26 | * query_up: 27 | * It takes two nodes u and v, condition is that v is an ancestor of u 28 | * We query the chain in which u is present till chain head, then move to next chain up 29 | * We do that way till u and v are in the same chain, we query for that part of chain and break 30 | */ 31 | 32 | int query_up(int u, int v) { 33 | if(u == v) return 0; // Trivial 34 | int uchain, vchain = chainInd[v], ans = -1, ret; 35 | // uchain and vchain are chain numbers of u and v 36 | while(true) { 37 | uchain = chainInd[u]; 38 | if(uchain == vchain) { 39 | // Both u and v are in the same chain, so we need to query from u to v, update answer and break. 40 | // We break because we came from u up till v, we are done 41 | if(u == v) break; 42 | ret = querySegTree(1, 0, ptr - 1, posInBase[v] + 1, posInBase[u]); 43 | // Above is call to segment tree query function 44 | ans = max(ans, ret); // Update answer 45 | break; 46 | } 47 | ret = querySegTree(1, 0, ptr - 1, posInBase[chainHead[uchain]], posInBase[u]); 48 | // Above is call to segment tree query function. We do from chainHead of u till u. That is the whole chain from 49 | // start till head. We then update the answer 50 | ans = max(ans, ret); 51 | u = chainHead[uchain]; // move u to u's chainHead 52 | u = table[u][0]; //Then move to its parent, that means we changed chains 53 | } 54 | return ans; 55 | } 56 | 57 | // See LCA section 58 | 59 | int lcaQuery(int u, int v); 60 | 61 | void lcaInit(int n); 62 | 63 | void query(int u, int v) { 64 | int lca = lcaQuery(u, v); 65 | int ans = max(query_up(v, lca), query_up(u, lca)); 66 | printf("%d\n", ans); 67 | } 68 | 69 | void change(int i, int val) { 70 | int u = otherEnd[i]; 71 | update(1, 0, ptr - 1, posInBase[u], val); 72 | } 73 | 74 | void HLD(int curNode = root, int cost = -1, int prev = -1) { 75 | if(chainHead[chainNo] == -1) { // Given a chain, what is the head of the chain 76 | chainHead[chainNo] = curNode; // Assign chain head 77 | } 78 | chainInd[curNode] = chainNo; // Given a node, to which chain does that node belong to 79 | //chainPos[cur] = chainSize[chainNo]; // Given a node, what is the position of that node in its chain 80 | //chainSize[chainNo]++; // Given a chain, what is the length of the chain 81 | posInBase[curNode] = ptr; // Position of this node in baseArray which we will use in Segtree 82 | baseArray[ptr++] = cost; 83 | 84 | int sc = -1, ncost; 85 | // Loop to find special child 86 | for(int i = 0, n = (int)adj[curNode].size(); i < n; i++) { 87 | int v = adj[curNode][i]; 88 | if(v != prev) { 89 | if(sc == -1 or subTreeSize[sc] < subTreeSize[v]) { 90 | sc = v, ncost = costs[curNode][i]; 91 | } 92 | } 93 | } 94 | 95 | if(sc != -1) { // Incase of curNode is leaf node 96 | // Expand the chain 97 | HLD(sc, ncost, curNode); 98 | } 99 | 100 | for(int i = 0, n = (int)adj[curNode].size(); i < n; i++) { 101 | int v = adj[curNode][i]; 102 | if(v != prev and v != sc) { 103 | // New chains at each normal node 104 | chainNo++; 105 | HLD(v, costs[curNode][i], curNode); 106 | } 107 | } 108 | } 109 | 110 | void dfs(int cur = root, int prev = -1, int _depth = 0) { 111 | table[cur][0] = prev; 112 | depth[cur] = _depth; 113 | subTreeSize[cur] = 1; 114 | for(int i = 0, n = (int)adj[cur].size(); i < n; i++) { 115 | int v = adj[cur][i]; 116 | if(v != prev) { 117 | otherEnd[indexx[cur][i]] = v; 118 | dfs(v, cur, _depth + 1); 119 | subTreeSize[cur] += subTreeSize[v]; 120 | } 121 | } 122 | } 123 | 124 | int main(void) { 125 | int tcase; 126 | scanf("%d", &tcase); 127 | while(tcase--) { 128 | ptr = 0; 129 | int n; 130 | scanf("%d", &n); 131 | // Cleaning step, new test case 132 | for(int i = 0; i < n; i++) { 133 | adj[i].clear(); 134 | costs[i].clear(); 135 | indexx[i].clear(); 136 | chainHead[i] = -1; 137 | for(int j = 0; i < LogN; i++) table[i][j] = -1; 138 | } 139 | for(int i = 0; i < n - 1; i++) { 140 | int u, v, cost; 141 | scanf("%d %d %d", &u, &v, &cost); 142 | u--, v--; 143 | adj[u].push_back(v); 144 | costs[u].push_back(cost); 145 | indexx[u].push_back(i); 146 | adj[v].push_back(u); 147 | costs[v].push_back(cost); 148 | indexx[v].push_back(i); 149 | } 150 | 151 | chainNo = 0; 152 | dfs(); // We set up subTreeSize, depth and parent for each node 153 | HLD(); // We decomposed the tree and created baseArray 154 | 155 | buildSegTree(); // We use baseArray and construct the needed segment tree 156 | 157 | lcaInit(n); 158 | 159 | while(true) { 160 | char s[100]; 161 | scanf("%s", s); 162 | if(s[0] == 'D') break; 163 | int a, b; 164 | scanf("%d %d", &a, &b); 165 | if(s[0] == 'Q') { 166 | query(a - 1, b - 1); 167 | } else { 168 | change(a - 1, b); 169 | } 170 | } 171 | } 172 | return 0; 173 | } -------------------------------------------------------------------------------- /algorithms/Huffman_coding.cpp: -------------------------------------------------------------------------------- 1 | // A Huffman tree node 2 | struct MinHeapNode { 3 | char data; // One of the input characters 4 | unsigned freq; // Frequency of the character 5 | MinHeapNode *left, *right; // Left and right child 6 | MinHeapNode(char data, unsigned freq): data(data), freq(freq), left(nullptr), right(nullptr) { 7 | } 8 | }; 9 | 10 | struct compare { 11 | bool operator()(MinHeapNode* lhs, MinHeapNode* rhs) { 12 | return (lhs->freq > rhs->freq); 13 | } 14 | }; 15 | 16 | void printCodes(struct MinHeapNode* root, string str) { 17 | if (!root) return; 18 | if (root->data != '$') { 19 | cout << root->data << ": " << str << "\n"; 20 | } 21 | printCodes(root->left, str + "0"); 22 | printCodes(root->right, str + "1"); 23 | } 24 | 25 | void huffmanCodes(unordered_map& freqMap) { 26 | priority_queue, compare> minHeap; 27 | for(auto iter = freqMap.begin(); iter != freqMap.end(); ++iter) { 28 | minHeap.push(new MinHeapNode(iter->first, iter->second)); 29 | } 30 | while (minHeap.size() != 1) { 31 | MinHeapNode* left = minHeap.top(); 32 | minHeap.pop(); 33 | MinHeapNode* right = minHeap.top(); 34 | minHeap.pop(); 35 | MinHeapNode* newNode = new MinHeapNode('#', left->freq + right->freq); 36 | newNode->left = left; 37 | newNode->right = right; 38 | minHeap.push(newNode); 39 | } 40 | 41 | printCodes(minHeap.top(), ""); 42 | } -------------------------------------------------------------------------------- /algorithms/Insertion_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* Time: O(n^2) */ 2 | void insertionSort(int *arr, int n) { 3 | for (int i = 1; i < n; i++) { 4 | int tmp = arr[i]; 5 | int j = i; 6 | while (j > 0 and tmp < arr[j - 1]) { 7 | arr[j] = arr[j - 1]; 8 | j--; 9 | } 10 | arr[j] = tmp; 11 | } 12 | } -------------------------------------------------------------------------------- /algorithms/InterpolationSearch.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to implement interpolation search 2 | #include 3 | using namespace std; 4 | 5 | // If x is present in arr[0..n-1], then returns 6 | // index of it, else returns -1. 7 | int interpolationSearch(int arr[], int n, int x) 8 | { 9 | // Find indexes of two corners 10 | int lo = 0, hi = (n - 1); 11 | 12 | // Since array is sorted, an element present 13 | // in array must be in range defined by corner 14 | while (lo <= hi && x >= arr[lo] && x <= arr[hi]) 15 | { 16 | if (lo == hi) 17 | { 18 | if (arr[lo] == x) return lo; 19 | return -1; 20 | } 21 | // Probing the position with keeping 22 | // uniform distribution in mind. 23 | int pos = lo + (((double)(hi - lo) / 24 | (arr[hi] - arr[lo])) * (x - arr[lo])); 25 | 26 | // Condition of target found 27 | if (arr[pos] == x) 28 | return pos; 29 | 30 | // If x is larger, x is in upper part 31 | if (arr[pos] < x) 32 | lo = pos + 1; 33 | 34 | // If x is smaller, x is in the lower part 35 | else 36 | hi = pos - 1; 37 | } 38 | return -1; 39 | } 40 | 41 | // Driver Code 42 | int main() 43 | { 44 | // Array of items on which search will 45 | // be conducted. 46 | int arr[] = {10, 12, 13, 16, 18, 19, 20, 21, 47 | 22, 23, 24, 33, 35, 42, 47}; 48 | int n = sizeof(arr)/sizeof(arr[0]); 49 | 50 | int x = 18; // Element to be searched 51 | int index = interpolationSearch(arr, n, x); 52 | 53 | // If element was found 54 | if (index != -1) 55 | cout << "Element found at index " << index; 56 | else 57 | cout << "Element not found."; 58 | return 0; 59 | } 60 | 61 | // This code is contributed by Mukul Singh. 62 | -------------------------------------------------------------------------------- /algorithms/Josephus_Recurrence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | General case for any k 3 | f(n, k) = ((f(n - 1, k) + k - 1) mod n) + 1, f(1, k) = 1 (when n = 1...8) 4 | */ 5 | int josephus(int n, int k) { 6 | if(n == 1) return 0; 7 | return (josephus(n - 1, k) + k) % n; 8 | } 9 | 10 | /* 11 | When k = 2 12 | Proof: wikipedia 13 | 2 * (n - 2^floor(log2n)) + 1 14 | */ 15 | int josephusfor2(int n) { 16 | return 2 * (n - pow(2, floor(log((double) n) / log(2.0)))) + 1; 17 | } 18 | 19 | /* 20 | another proof for k = 2 21 | source: wikipedia 22 | n = 1b1b2b3b4...bm (bit representaion), ans = b1b2b3b4...bm1 (shifting leftmost bit into rightmost) 23 | */ 24 | int josephusfor2_bit(int n) { 25 | n <<= 1; 26 | n |= 1; 27 | int bit = floor((double)log(n) / log(2.0)); 28 | int var = (1 << bit); 29 | --var; 30 | n &= var; 31 | return n; 32 | } -------------------------------------------------------------------------------- /algorithms/JumpSearch.cpp: -------------------------------------------------------------------------------- 1 | // C++ program to implement Jump Search 2 | 3 | #include 4 | using namespace std; 5 | 6 | int jumpSearch(int arr[], int x, int n) 7 | { 8 | // Finding block size to be jumped 9 | int step = sqrt(n); 10 | 11 | // Finding the block where element is 12 | // present (if it is present) 13 | int prev = 0; 14 | while (arr[min(step, n)-1] < x) 15 | { 16 | prev = step; 17 | step += sqrt(n); 18 | if (prev >= n) 19 | return -1; 20 | } 21 | 22 | // Doing a linear search for x in block 23 | // beginning with prev. 24 | while (arr[prev] < x) 25 | { 26 | prev++; 27 | 28 | // If we reached next block or end of 29 | // array, element is not present. 30 | if (prev == min(step, n)) 31 | return -1; 32 | } 33 | // If element is found 34 | if (arr[prev] == x) 35 | return prev; 36 | 37 | return -1; 38 | } 39 | // Tìm kiếm tuyến tính < Tìm kiếm nhảy < Tìm kiếm nhị phân 40 | // Áp dụng cho các dãy số có tính tăng dần hoặc giảm dần. Ở ví dụ thì đag ở trường hợp dãy tăng 41 | // Driver program to test function 42 | int main() 43 | { 44 | int n,x,i; 45 | cin >> n; 46 | int arr[n]; 47 | for (i = 0; i < n; i++) cin >> arr[i]; 48 | cin >> x; 49 | 50 | // Find the index of 'x' using Jump Search 51 | int index = jumpSearch(arr, x, n); 52 | 53 | // Print the index where 'x' is located 54 | cout << "\nNumber " << x << " is at index " << index; 55 | return 0; 56 | } 57 | 58 | // Contributed by nuclode -------------------------------------------------------------------------------- /algorithms/Kruskal’s_Minimum_Spanning_Tree.cpp: -------------------------------------------------------------------------------- 1 | // C++ program for the above approach 2 | 3 | #include 4 | using namespace std; 5 | 6 | // DSU data structure 7 | // path compression + rank by union 8 | 9 | class DSU { 10 | int* parent; 11 | int* rank; 12 | 13 | public: 14 | DSU(int n) 15 | { 16 | parent = new int[n]; 17 | rank = new int[n]; 18 | 19 | for (int i = 0; i < n; i++) { 20 | parent[i] = -1; 21 | rank[i] = 1; 22 | } 23 | } 24 | 25 | // Find function 26 | int find(int i) 27 | { 28 | if (parent[i] == -1) 29 | return i; 30 | 31 | return parent[i] = find(parent[i]); 32 | } 33 | 34 | // Union function 35 | void unite(int x, int y) 36 | { 37 | int s1 = find(x); 38 | int s2 = find(y); 39 | 40 | if (s1 != s2) { 41 | if (rank[s1] < rank[s2]) { 42 | parent[s1] = s2; 43 | rank[s2] += rank[s1]; 44 | } 45 | else { 46 | parent[s2] = s1; 47 | rank[s1] += rank[s2]; 48 | } 49 | } 50 | } 51 | }; 52 | 53 | class Graph { 54 | vector > edgelist; 55 | int V; 56 | 57 | public: 58 | Graph(int V) { this->V = V; } 59 | 60 | void addEdge(int x, int y, int w) 61 | { 62 | edgelist.push_back({ w, x, y }); 63 | } 64 | 65 | void kruskals_mst() 66 | { 67 | // 1. Sort all edges 68 | sort(edgelist.begin(), edgelist.end()); 69 | 70 | // Initialize the DSU 71 | DSU s(V); 72 | int ans = 0; 73 | cout << "Following are the edges in the " 74 | "constructed MST" 75 | << endl; 76 | for (auto edge : edgelist) { 77 | int w = edge[0]; 78 | int x = edge[1]; 79 | int y = edge[2]; 80 | 81 | // Take this edge in MST if it does 82 | // not forms a cycle 83 | if (s.find(x) != s.find(y)) { 84 | s.unite(x, y); 85 | ans += w; 86 | cout << x << " -- " << y << " == " << w 87 | << endl; 88 | } 89 | } 90 | 91 | cout << "Minimum Cost Spanning Tree: " << ans; 92 | } 93 | }; 94 | 95 | // Driver's code 96 | int main() 97 | { 98 | /* Let us create following weighted graph 99 | 10 100 | 0--------1 101 | | \ | 102 | 6| 5\ |15 103 | | \ | 104 | 2--------3 105 | 4 */ 106 | Graph g(4); 107 | g.addEdge(0, 1, 10); 108 | g.addEdge(1, 3, 15); 109 | g.addEdge(2, 3, 4); 110 | g.addEdge(2, 0, 6); 111 | g.addEdge(0, 3, 5); 112 | 113 | // Function call 114 | g.kruskals_mst(); 115 | return 0; 116 | } -------------------------------------------------------------------------------- /algorithms/LinearSearch.cpp: -------------------------------------------------------------------------------- 1 | // C++ code to linearly search x in arr[]. If x 2 | // is present then return its location, otherwise 3 | // return -1 4 | 5 | #include 6 | using namespace std; 7 | 8 | int search(int arr[], int N, int x) 9 | { 10 | int i; 11 | for (i = 0; i < N; i++) 12 | if (arr[i] == x) 13 | return i; 14 | return -1; 15 | } 16 | // Thuật toán tìm kiếm bằng cách xét từng chỉ số của mảng. 17 | // Driver's code 18 | int main() 19 | { 20 | int n,x,i; 21 | cin >> n; 22 | int arr[n]; 23 | for (i = 0; i < n; i++) cin >> arr[i]; 24 | cin >> x; 25 | 26 | // Function call 27 | int result = search(arr, n, x); 28 | (result == -1) 29 | ? cout << "Element is not present in array" 30 | : cout << "Element is present at index " << result; 31 | return 0; 32 | } -------------------------------------------------------------------------------- /algorithms/Maximum_Flow_Problem_I_Edmond_Karp.cpp: -------------------------------------------------------------------------------- 1 | // Ford-Fulkerson + Edmond Karp algorithm 2 | // single source - single sink maximum flow 3 | #define MAX 1005 4 | 5 | vector> adj[MAX]; // adj[u] = {{v1, capacity1}, {v2, capacity2}} 6 | vector residual[MAX]; // residual[u][v1] = capacity1 7 | int parent[MAX]; 8 | bool visited[MAX]; 9 | int n; 10 | 11 | /* Returns true if there is a path from 'src' to 'sink' in 12 | residual graph. Also fills parent[] to store the path */ 13 | bool bfs(int src, int sink) { 14 | memset(visited, false, sizeof visited); 15 | queue q; 16 | q.push(src); 17 | visited[src] = true; 18 | parent[src] = -1; 19 | 20 | while (!q.empty()) { 21 | int u = q.front(); 22 | q.pop(); 23 | for(int i = 0; i < (int)adj[u].size(); i++) { 24 | int v = adj[u][i].first; 25 | if(!visited[v] and residual[u][v] > 0) { 26 | q.push(v); 27 | parent[v] = u; 28 | visited[v] = true; 29 | } 30 | } 31 | } 32 | 33 | // If we reached sink in BFS starting from source, then return true, else false 34 | return visited[sink]; 35 | } 36 | 37 | int edmondKarp(int src, int sink) { 38 | int maxFlow = 0; 39 | for(int u = 0; u < n; u++) { 40 | for(int i = 0; i < (int)adj[u].size(); i++) { 41 | int v = adj[u][i].first; 42 | int capacity = adj[u][i].second; 43 | residual[u][v] = capacity; 44 | } 45 | } 46 | while(bfs(src, sink)) { 47 | int pathFlow = INT_MAX; 48 | // trace augmenting path 49 | int v = sink; 50 | while(v != src) { 51 | int u = parent[v]; 52 | pathFlow = min(pathFlow, residual[u][v]); 53 | v = u; 54 | } 55 | 56 | // update residual graph 57 | v = sink; 58 | while(v != src) { 59 | int u = parent[v]; 60 | residual[u][v] -= pathFlow; 61 | residual[v][u] += pathFlow; 62 | v = u; 63 | } 64 | 65 | maxFlow += pathFlow; 66 | } 67 | 68 | return maxFlow; 69 | } -------------------------------------------------------------------------------- /algorithms/Merge_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time: O(nlogn) 3 | Extra Space: Omega(n) [O(n) + O(logn) = allocating n elements + stack frame] 4 | */ 5 | void merge(int* arr, int left, int mid, int right) { 6 | int i, j, k; 7 | int n1 = mid - left + 1; 8 | int n2 = right - mid; 9 | 10 | /* create temp arrays */ 11 | int L[n1], R[n2]; 12 | 13 | /* Copy data to temp arrays L[] and R[] */ 14 | for(i = 0; i < n1; i++) L[i] = arr[left + i]; 15 | for(j = 0; j <= n2; j++) R[j] = arr[mid + 1 + j]; 16 | 17 | /* Merge the temp arrays back into arr[l..r]*/ 18 | i = 0, j = 0, k = left; 19 | while (i < n1 and j < n2) 20 | arr[k++] = L[i] <= R[j] ? L[i++] : R[j++]; 21 | 22 | /* Copy the remaining elements of L[], if there are any */ 23 | while (i < n1) 24 | arr[k++] = L[i++]; 25 | 26 | /* Copy the remaining elements of R[], if there are any */ 27 | while (j < n2) 28 | arr[k++] = R[j++]; 29 | } 30 | 31 | void mergeSort(int* arr, int left, int right) { 32 | if (left < right) { 33 | int mid = left + (right - left) / 2; //Same as (l + r) / 2, but avoids overflow for large left and right 34 | mergeSort(arr, left, mid); 35 | mergeSort(arr, mid + 1, right); 36 | merge(arr, left, mid, right); 37 | } 38 | } -------------------------------------------------------------------------------- /algorithms/Minimum_expression.cpp: -------------------------------------------------------------------------------- 1 | // return the position of rotation of a string such that 2 | // the resulting string is lexicographically smallest 3 | // Time : O(n) 4 | // https://www.quora.com/How-does-the-minimum-expression-algorithm-by-Zhou-Yuan-work 5 | int minimumExpression(string s) { 6 | s += s; 7 | size_t n = s.length(); 8 | int i = 0, j = 1, k = 0; 9 | while(i + k < n and j + k < n) { 10 | if(s[i + k] == s[j + k]) k++; 11 | else if(s[i + k] > s[j + k]) { 12 | i = i + k + 1; 13 | if(i <= j) i = j + 1; 14 | k = 0; 15 | } 16 | else if(s[i + k] < s[j + k]) { 17 | j = j + k + 1; 18 | if(j <= i) j = i + 1; 19 | k = 0; 20 | } 21 | } 22 | return min(i, j); 23 | } -------------------------------------------------------------------------------- /algorithms/Pancake_sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Complexity: O(n^2) 3 | Goal is to sort the sequence in as few reversals as possible 4 | */ 5 | 6 | /* Reverses arr[0..k] */ 7 | void flip(vector& arr, int k) { 8 | for(int left = 0, right = k; left < right; ++left, --right) { 9 | swap(arr[left], arr[right]); 10 | } 11 | } 12 | 13 | /* Returns index of the maximum element in arr[0..n-1] */ 14 | int findMax(vector& arr, int k) { 15 | int Max = 0; 16 | for (int i = 0; i < k; ++i) { 17 | if(arr[i] > arr[Max]) { 18 | Max = i; 19 | } 20 | } 21 | return Max; 22 | } 23 | 24 | void pancakeSort(vector& arr) { 25 | // Start from the complete array and one by one reduce current size by one 26 | for (int n = (int)arr.size(), k = n; k > 1; --k) { 27 | // Find index of the maximum element in arr[0..k - 1] 28 | int mIndx = findMax(arr, k); 29 | 30 | // Move the maximum element to end of current array if it's not 31 | // already at the end 32 | if (mIndx != k - 1) { 33 | // To move at the end, first move maximum number to beginning 34 | flip(arr, mIndx); 35 | 36 | // Now move the maximum number to end by reversing current array 37 | flip(arr, k - 1); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /algorithms/Power.cpp: -------------------------------------------------------------------------------- 1 | int powerUtil(int base, int exp, int mod) { 2 | if(exp == 0) return 1; 3 | int ret = powerUtil(base, exp / 2, mod) % mod; 4 | ret = 1LL * ret * ret % mod; 5 | if(exp & 1) { 6 | ret = 1LL * ret * base % mod; 7 | } 8 | return ret; 9 | } 10 | 11 | double power(int base, int exp, int mod = 1000000007) { 12 | if(exp < 0) { 13 | if(base == 0) return DBL_MAX; // undefined 14 | return 1 / (double) powerUtil(base, -exp, mod); // return type will be double/long double then 15 | } 16 | return powerUtil(base, exp, mod); 17 | } 18 | 19 | // Modular mutiplicative inverse 20 | int modInv(int base, int mod = 1000000007) { 21 | return powerUtil(base, mod - 2, mod); 22 | } -------------------------------------------------------------------------------- /algorithms/Prim’s_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | // STL implementation of Prim's algorithm for MST 2 | #include 3 | using namespace std; 4 | # define INF 0x3f3f3f3f 5 | 6 | // iPair ==> Integer Pair 7 | typedef pair iPair; 8 | 9 | // This class represents a directed graph using 10 | // adjacency list representation 11 | class Graph 12 | { 13 | int V; // No. of vertices 14 | 15 | // In a weighted graph, we need to store vertex 16 | // and weight pair for every edge 17 | list< pair > *adj; 18 | 19 | public: 20 | Graph(int V); // Constructor 21 | 22 | // function to add an edge to graph 23 | void addEdge(int u, int v, int w); 24 | 25 | // Print MST using Prim's algorithm 26 | void primMST(); 27 | }; 28 | 29 | // Allocates memory for adjacency list 30 | Graph::Graph(int V) 31 | { 32 | this->V = V; 33 | adj = new list [V]; 34 | } 35 | 36 | void Graph::addEdge(int u, int v, int w) 37 | { 38 | adj[u].push_back(make_pair(v, w)); 39 | adj[v].push_back(make_pair(u, w)); 40 | } 41 | 42 | // Prints shortest paths from src to all other vertices 43 | void Graph::primMST() 44 | { 45 | // Create a priority queue to store vertices that 46 | // are being primMST. This is weird syntax in C++. 47 | // Refer below link for details of this syntax 48 | // http://geeksquiz.com/implement-min-heap-using-stl/ 49 | priority_queue< iPair, vector , greater > pq; 50 | 51 | int src = 0; // Taking vertex 0 as source 52 | 53 | // Create a vector for keys and initialize all 54 | // keys as infinite (INF) 55 | vector key(V, INF); 56 | 57 | // To store parent array which in turn store MST 58 | vector parent(V, -1); 59 | 60 | // To keep track of vertices included in MST 61 | vector inMST(V, false); 62 | 63 | // Insert source itself in priority queue and initialize 64 | // its key as 0. 65 | pq.push(make_pair(0, src)); 66 | key[src] = 0; 67 | 68 | /* Looping till priority queue becomes empty */ 69 | while (!pq.empty()) 70 | { 71 | // The first vertex in pair is the minimum key 72 | // vertex, extract it from priority queue. 73 | // vertex label is stored in second of pair (it 74 | // has to be done this way to keep the vertices 75 | // sorted key (key must be first item 76 | // in pair) 77 | int u = pq.top().second; 78 | pq.pop(); 79 | 80 | //Different key values for same vertex may exist in the priority queue. 81 | //The one with the least key value is always processed first. 82 | //Therefore, ignore the rest. 83 | if(inMST[u] == true){ 84 | continue; 85 | } 86 | 87 | inMST[u] = true; // Include vertex in MST 88 | 89 | // 'i' is used to get all adjacent vertices of a vertex 90 | list< pair >::iterator i; 91 | for (i = adj[u].begin(); i != adj[u].end(); ++i) 92 | { 93 | // Get vertex label and weight of current adjacent 94 | // of u. 95 | int v = (*i).first; 96 | int weight = (*i).second; 97 | 98 | // If v is not in MST and weight of (u,v) is smaller 99 | // than current key of v 100 | if (inMST[v] == false && key[v] > weight) 101 | { 102 | // Updating key of v 103 | key[v] = weight; 104 | pq.push(make_pair(key[v], v)); 105 | parent[v] = u; 106 | } 107 | } 108 | } 109 | 110 | // Print edges of MST using parent array 111 | for (int i = 1; i < V; ++i) 112 | printf("%d - %d\n", parent[i], i); 113 | } 114 | 115 | // Driver program to test methods of graph class 116 | int main() 117 | { 118 | // create the graph given in above figure 119 | int V = 9; 120 | Graph g(V); 121 | 122 | // making above shown graph 123 | g.addEdge(0, 1, 4); 124 | g.addEdge(0, 7, 8); 125 | g.addEdge(1, 2, 8); 126 | g.addEdge(1, 7, 11); 127 | g.addEdge(2, 3, 7); 128 | g.addEdge(2, 8, 2); 129 | g.addEdge(2, 5, 4); 130 | g.addEdge(3, 4, 9); 131 | g.addEdge(3, 5, 14); 132 | g.addEdge(4, 5, 10); 133 | g.addEdge(5, 6, 2); 134 | g.addEdge(6, 7, 1); 135 | g.addEdge(6, 8, 6); 136 | g.addEdge(7, 8, 7); 137 | 138 | g.primMST(); 139 | 140 | return 0; 141 | } -------------------------------------------------------------------------------- /algorithms/Quick_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time: O(nlogn) 3 | Extra Space: O(logn) 4 | This function takes last element as pivot, places the pivot element at its 5 | correct position in sorted array, and places all smaller (smaller than pivot) 6 | to left of pivot and all greater elements to right of pivot 7 | */ 8 | int partition (int* arr, int left, int right) { 9 | int pivot = arr[right]; 10 | int i = left - 1; // Index of smaller element 11 | 12 | for (int j = left; j < right; j++) { 13 | if (arr[j] <= pivot) 14 | swap(arr[++i], arr[j]); // Swap current element with index 15 | } 16 | swap(arr[++i], arr[right]); 17 | return i; 18 | } 19 | 20 | void quickSort(int* arr, int left, int right) { 21 | if (left < right) { 22 | int pos = partition(arr, left, right); 23 | quickSort(arr, left, pos - 1); 24 | quickSort(arr, pos + 1, right); 25 | } 26 | } -------------------------------------------------------------------------------- /algorithms/Radix_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Compleixty: Long story, bro! See http://www.geeksforgeeks.org/radix-sort/ 3 | */ 4 | 5 | void countSort(int* arr, int n, int exp) { 6 | int output[n]; // output array 7 | int i, count[10] = {0}; 8 | 9 | // Store count of occurrences in count[] 10 | for (i = 0; i < n; i++) 11 | count[ (arr[i] / exp) % 10 ]++; 12 | 13 | // Change count[i] so that count[i] now contains actual position of 14 | // this digit in output[] 15 | for (i = 1; i < 10; i++) 16 | count[i] += count[i - 1]; 17 | 18 | // Build the output array 19 | int indx; 20 | for (i = n - 1; i >= 0; i--) { 21 | indx = (arr[i] / exp) % 10; 22 | output[count[indx] - 1] = arr[i]; 23 | count[indx]--; 24 | } 25 | 26 | // Copy the output array to arr[], so that arr[] now 27 | // contains sorted numbers according to curent digit 28 | for (i = 0; i < n; i++) 29 | arr[i] = output[i]; 30 | } 31 | 32 | // The main function to that sorts arr[] of size n using Radix Sort 33 | void radixsort(int* arr, int n) { 34 | // Find the maximum number to know number of digits 35 | int m = *max_element(arr, arr + n); 36 | 37 | // Do counting sort for every digit. Note that instead of passing digit 38 | // number, exp is passed. exp is 10^i where i is current digit number 39 | for (int exp = 1; m / exp > 0; exp *= 10) 40 | countSort(arr, n, exp); 41 | } -------------------------------------------------------------------------------- /algorithms/Selection_Sort.cpp: -------------------------------------------------------------------------------- 1 | /* Time: O(n^2) */ 2 | void selectionSort(int* arr, int n) { 3 | int minIndx; 4 | for(int i = 0; i < n - 1; i++) { 5 | minIndx = i; 6 | for(int j = i + 1; j < n; ++j) { 7 | if(arr[j] < arr[minIndx]) 8 | minIndx = j; 9 | } 10 | swap(arr[i], arr[minIndx]); 11 | } 12 | } -------------------------------------------------------------------------------- /algorithms/TernarySearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int ternaryI(int a[], int target, int n) 5 | { 6 | int l = 0; 7 | int r = n-1; 8 | 9 | while( r-l>=0 ) { 10 | int partiton = (r-l)/3; 11 | int mid1 = l + partiton; 12 | int mid2 = r - partiton; 13 | 14 | if ( target == a[mid1]) 15 | return mid1; 16 | else if ( target == a[mid2]) 17 | return mid2; 18 | else if ( target < a[mid1] ) 19 | r = mid1-1; 20 | else if ( target > a[mid2] ) 21 | l = mid2+1; 22 | else { 23 | l = mid1+1; 24 | r = mid2-1; 25 | } 26 | } // while ends 27 | 28 | return -1; 29 | } // function ends 30 | 31 | 32 | 33 | int main() 34 | { 35 | int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 36 | int n = 10; 37 | int target = 7; 38 | 39 | int tsi = ternaryI(arr, target, n); 40 | cout << "Result of TSI = " << tsi << endl; 41 | 42 | return 0; 43 | } // main ends -------------------------------------------------------------------------------- /algorithms/Trie.cpp: -------------------------------------------------------------------------------- 1 | const static int SIZE = 30; 2 | const static int NOT_FOUND = -1; 3 | class trie { 4 | private: 5 | struct trieNode { 6 | int mark; 7 | trieNode* children[SIZE]; 8 | trieNode(): mark(NOT_FOUND) { 9 | for (int i = 0; i < SIZE; ++i) { 10 | children[i] = nullptr; 11 | } 12 | } 13 | ~trieNode() { 14 | for (int i = 0; i < SIZE; ++i) { 15 | delete children[i]; 16 | children[i] = nullptr; 17 | } 18 | } 19 | }; 20 | trieNode* root; 21 | public: 22 | trie(): root(new trieNode()) { 23 | } 24 | ~trie() { 25 | delete root; 26 | root = nullptr; 27 | } 28 | 29 | void insert(string const& key, int id) { 30 | trieNode* pCrawl = root; 31 | for (int i = 0; i < (int)key.length(); ++i) { 32 | int indx = key[i] - 'a'; 33 | if (!pCrawl->children[indx]) { 34 | pCrawl->children[indx] = new trieNode(); 35 | } 36 | pCrawl = pCrawl->children[indx]; 37 | } 38 | pCrawl->mark = id; 39 | } 40 | 41 | int search(string const& key) { 42 | trieNode *pCrawl = root; 43 | for (int i = 0; i < (int)key.length(); ++i) { 44 | int indx = key[i] - 'a'; 45 | if (!pCrawl->children[indx]) { 46 | return NOT_FOUND; 47 | } 48 | pCrawl = pCrawl->children[indx]; 49 | } 50 | return pCrawl->mark; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /algorithms/articulation_point.cpp: -------------------------------------------------------------------------------- 1 | // low[u] be the earliest discovery time of any vertex in the subtree rooted at u or connected to a vertex in that subtree by a back edge. 2 | vector adj[MAX]; 3 | int low[MAX], disc[MAX], parent[MAX], dfstime, cnt = 0, N; 4 | bool ap[MAX], visited[MAX]; 5 | 6 | void dfs(int u) { 7 | int children = 0; 8 | visited[u] = true; 9 | disc[u] = low[u] = ++dfstime; 10 | 11 | // If some child v of u has low[v] >= disc_time[u], then u is an articulation point. 12 | // low[u] = min( {low[v] | v is a child of u} and {disc_time[x] | (u, x) is a back edge from u or any child-vertex of it} ) 13 | 14 | for(int i = 0; i < (int)adj[u].size(); i++) { 15 | int v = adj[u][i]; 16 | 17 | if(!visited[v]) { 18 | ++children; 19 | parent[v] = u; 20 | dfs(v); 21 | // Check if the subtree rooted with v has a connection to 22 | // one of the ancestors of u 23 | low[u] = min(low[u], low[v]); 24 | 25 | // u is an articulation point in following cases 26 | 27 | // (1) u is root of DFS tree and has two or more children. 28 | if (parent[u] == -1 and children > 1) 29 | ap[u] = true; 30 | 31 | // (2) If u is not root and low value of one of its child is more 32 | // than discovery value of u. 33 | if (parent[u] != -1 and low[v] >= disc[u]) 34 | ap[u] = true; 35 | 36 | } else if(v != parent[u]) // Update low value of u for parent function calls. 37 | low[u] = min(low[u], disc[v]); 38 | } 39 | 40 | } 41 | 42 | void tarjanAP() { 43 | memset(ap, false, sizeof ap); 44 | memset(visited, false, sizeof visited); 45 | memset(parent, -1, sizeof parent); 46 | dfstime = 0, cnt = 0; 47 | 48 | for(int i = 1; i <= N; ++i) if(!visited[i]) dfs(i); 49 | 50 | for(int i = 1; i <= N; ++i) if(ap[i]) printf("%d ", i), ++cnt; 51 | } -------------------------------------------------------------------------------- /algorithms/bellman_fords.cpp: -------------------------------------------------------------------------------- 1 | #define pii pair 2 | #define INF (1 << 30) 3 | #define MAX 100001 4 | vector node[MAX]; 5 | int dis[MAX + 1]; 6 | int vertex_no; 7 | vector < pair > node[MAX + 1]; 8 | 9 | // Time Complexity: O(V * E) 10 | int bellman_ford(int src) { 11 | fill_n(dis, MAX, INF); 12 | dis[src] = 0; 13 | // relaxing E edges V - 1 times exactly 14 | for(int k = 0; k < vertex_no - 1; ++k) // O(V) 15 | for(int u = 0; u < vertex_no; ++u) for(int i = 0; i < (int)node[u].size(); ++i) { // O(E) 16 | int v = node[u][i].first, cost = node[u][i].second; 17 | dis[v] = min(dis[v], dis[u] + cost); 18 | } 19 | // rep(i, vertex_no) print(dis[i]); 20 | } 21 | 22 | // check whether a graph has any negative cycle 23 | bool has_negative_cycle(int src) { 24 | bellman_ford(src); 25 | for(int u = 0; u < vertex_no; ++u) for(int i = 0; i < (int)node[u].size(); ++i) { 26 | int v = node[u][i].first, cost = node[u][i].second; 27 | if(dis[v] > dis[u] + cost) 28 | return true; 29 | } 30 | return false; 31 | } -------------------------------------------------------------------------------- /algorithms/berenstain_hashing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Source: Zobayer Blog 3 | Must use unsigned type. 4 | hash = hash * 33 ^ c, reliable hash 5 | */ 6 | 7 | #define u64 unsigned long long 8 | 9 | u64 hash(string const& s) { 10 | u64 hash = 0; 11 | for(int i = 0; i < (int)s.length(); i++) { 12 | int c = s[i]; 13 | hash = ((hash << 5) + hash) ^ c; 14 | } 15 | return hash; 16 | } -------------------------------------------------------------------------------- /algorithms/bfs.cpp: -------------------------------------------------------------------------------- 1 | vector adj[Max]; 2 | int visited[Max], dis[Max + 1]; 3 | queue q; 4 | 5 | void BFS(int src) { 6 | q.push(src); 7 | dis[src] = 0; 8 | visited[src] = true; 9 | printf("Level %d: %d\n", dis[src], src); 10 | while(!q.empty()) { 11 | int pop = q.front(), temp; 12 | for(int i = 0, n = (int)adj[pop].size(); i < n; i++) { 13 | temp = adj[pop][i]; 14 | if(!visited[temp]) { 15 | dis[temp] = dis[pop] + 1; 16 | visited[temp] = 1; 17 | q.push(temp); 18 | printf("Level %d: %d\n", dis[temp], temp); 19 | } 20 | } 21 | q.pop(); 22 | } 23 | } -------------------------------------------------------------------------------- /algorithms/big_integer.cpp: -------------------------------------------------------------------------------- 1 | struct BigInt { 2 | // representations and structures 3 | string a; // to store the digits 4 | int sign; // sign = -1 for negative numbers, sign = 1 otherwise 5 | 6 | // constructors 7 | BigInt() {} // default constructor 8 | BigInt( string b ) { 9 | (*this) = b; // constructor for string 10 | } 11 | 12 | // some helpful methods 13 | int size() { // returns number of digits 14 | return a.size(); 15 | } 16 | BigInt inverseSign() { // changes the sign 17 | sign *= -1; 18 | return (*this); 19 | } 20 | BigInt normalize( int newSign ) { // removes leading 0, fixes sign 21 | for( int i = a.size() - 1; i > 0 && a[i] == '0'; i-- ) 22 | a.erase(a.begin() + i); 23 | sign = ( a.size() == 1 && a[0] == '0' ) ? 1 : newSign; 24 | return (*this); 25 | } 26 | 27 | // assignment operator 28 | void operator = ( string b ) { // assigns a string to BigInt 29 | a = b[0] == '-' ? b.substr(1) : b; 30 | reverse( a.begin(), a.end() ); 31 | this->normalize( b[0] == '-' ? -1 : 1 ); 32 | } 33 | 34 | // conditional operators 35 | bool operator < ( const BigInt &b ) const { // less than operator 36 | if( sign != b.sign ) return sign < b.sign; 37 | if( a.size() != b.a.size() ) 38 | return sign == 1 ? a.size() < b.a.size() : a.size() > b.a.size(); 39 | for( int i = a.size() - 1; i >= 0; i-- ) if( a[i] != b.a[i] ) 40 | return sign == 1 ? a[i] < b.a[i] : a[i] > b.a[i]; 41 | return false; 42 | } 43 | bool operator == ( const BigInt &b ) const { // operator for equality 44 | return a == b.a && sign == b.sign; 45 | } 46 | 47 | 48 | 49 | // mathematical operators 50 | BigInt operator + ( BigInt b ) { // addition operator overloading 51 | if( sign != b.sign ) return (*this) - b.inverseSign(); 52 | BigInt c; 53 | for(int i = 0, carry = 0; i= 0 ? borrow + 48 : borrow + 58; 69 | borrow = borrow >= 0 ? 0 : 1; 70 | } 71 | return c.normalize(s); 72 | } 73 | BigInt operator * ( BigInt b ) { // multiplication operator overloading 74 | BigInt c("0"); 75 | for( int i = 0, k = a[i] - 48; i < a.size(); i++, k = a[i] - 48 ) { 76 | while(k--) c = c + b; // ith digit is k, so, we add k times 77 | b.a.insert(b.a.begin(), '0'); // multiplied by 10 78 | } 79 | return c.normalize(sign * b.sign); 80 | } 81 | BigInt operator / ( BigInt b ) { // division operator overloading 82 | if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 ); 83 | BigInt c("0"), d; 84 | for( int j = 0; j < a.size(); j++ ) d.a += "0"; 85 | int dSign = sign * b.sign; 86 | b.sign = 1; 87 | for( int i = a.size() - 1; i >= 0; i-- ) { 88 | c.a.insert( c.a.begin(), '0'); 89 | c = c + a.substr( i, 1 ); 90 | while( !( c < b ) ) c = c - b, d.a[i]++; 91 | } 92 | return d.normalize(dSign); 93 | } 94 | BigInt operator % ( BigInt b ) { // modulo operator overloading 95 | if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 ); 96 | BigInt c("0"); 97 | b.sign = 1; 98 | for( int i = a.size() - 1; i >= 0; i-- ) { 99 | c.a.insert( c.a.begin(), '0'); 100 | c = c + a.substr( i, 1 ); 101 | while( !( c < b ) ) c = c - b; 102 | } 103 | return c.normalize(sign); 104 | } 105 | 106 | // faster output method 107 | void _print() { 108 | if( sign == -1 ) putchar('-'); 109 | for( int i = a.size() - 1; i >= 0; i-- ) putchar(a[i]); 110 | } 111 | }; 112 | 113 | ostream& operator << (ostream& os, const BigInt& obj) { 114 | if( obj.sign == -1 ) os << "-"; 115 | for( int i = obj.a.size() - 1; i >= 0; i--) os << obj.a[i]; 116 | return os; 117 | } -------------------------------------------------------------------------------- /algorithms/binary_search.cpp: -------------------------------------------------------------------------------- 1 | int lowerBound(vector& arr, int target) { 2 | int n = (int)arr.size(); 3 | int left = 0, right = n - 1; 4 | int indx = -1; 5 | while(left <= right) { 6 | int mid = left + (right - left) / 2; 7 | if(arr[mid] == target) { 8 | indx = mid; 9 | } 10 | if(arr[mid] < target) { 11 | left = mid + 1; 12 | } else { // arr[mid] >= target 13 | right = mid - 1; 14 | } 15 | } 16 | return indx; 17 | } 18 | 19 | // different from C++ upper_bound. return target's index inclusive 20 | int upperBound(vector& arr, int target) { 21 | int n = (int)arr.size(); 22 | int left = 0, right = n - 1; 23 | int indx = -1; 24 | while(left <= right) { 25 | int mid = left + (right - left) / 2; 26 | if(arr[mid] == target) { 27 | indx = mid; 28 | } 29 | if(arr[mid] <= target) { 30 | left = mid + 1; 31 | } else { // arr[mid] > target 32 | right = mid - 1; 33 | } 34 | } 35 | return indx; 36 | } 37 | 38 | pair equalRange(vector& arr, int target) { 39 | int lbound = lowerBound(arr, target); 40 | int ubound = upperBound(arr, target); 41 | return pair{lbound, ubound}; 42 | } 43 | 44 | int binarySearch(vector& arr, int target) { 45 | int lbound = lowerBound(arr, target); 46 | return lbound; 47 | } -------------------------------------------------------------------------------- /algorithms/bipartite_graph_check.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define MAX 100000 8 | 9 | vector adj[MAX]; 10 | array color; 11 | array visited; 12 | 13 | bool isGraphBipartite(int src) { 14 | color.fill(-1); 15 | visited.fill(false); 16 | queue Q; 17 | Q.push(src); 18 | color[src] = 1; 19 | visited[src] = true; 20 | while (!Q.empty()) { 21 | int u = Q.front(); 22 | Q.pop(); 23 | for (int i = 0; i < (int)adj[u].size(); i++) { 24 | int v = adj[u][i]; 25 | if (!visited[v]) { 26 | visited[v] = true; 27 | color[v] = 1 - color[u]; 28 | Q.push(v); 29 | } else if (visited[v] and color[v] == color[u]) { 30 | return false; 31 | } 32 | } 33 | } 34 | return true; 35 | } -------------------------------------------------------------------------------- /algorithms/bridge.cpp: -------------------------------------------------------------------------------- 1 | // low[u] be the earliest discovery time of any vertex in the subtree rooted at u or connected to a vertex in that subtree by a back edge. 2 | int low[MAX], disc[MAX], parent[MAX], dfstime; 3 | bool visited[MAX]; 4 | vector adj[MAX], result; 5 | 6 | void dfs(int u) { 7 | visited[u] = true; 8 | disc[u] = low[u] = ++dfstime; 9 | 10 | // If some child v of u has low[v] >= disc_time[u], then u is an articulation point. 11 | // low[u] = min( {low[v] | v is a child of u} and {disc_time[x] | (u, x) is a back edge from u or any child-vertex of it} ) 12 | 13 | for(int i = 0; i < (int)adj[u].size(); i++) { 14 | int v = adj[u][i]; 15 | 16 | if(!visited[v]) { 17 | ++children; 18 | parent[v] = u; 19 | dfs(v); 20 | // Check if the subtree rooted with v has a connection to 21 | // one of the ancestors of u 22 | low[u] = min(low[u], low[v]); 23 | 24 | // If the lowest vertex reachable from subtree under v is 25 | // below u in DFS tree, then u-v is a bridge 26 | if (low[v] > disc[u]) result.push_back(Point(u, v)); 27 | 28 | } else if(v != parent[u]) // Update low value of u for parent function calls. 29 | low[u] = min(low[u], disc[v]); 30 | } 31 | 32 | } 33 | 34 | void tarjanBridge() { 35 | memset(visited, false, sizeof visited); 36 | memset(parent, -1, sizeof parent); 37 | dfstime = 0; 38 | for(int i = 0; i < N; ++i) if(!visited[i]) tarjan(i); 39 | } -------------------------------------------------------------------------------- /algorithms/coin_change.cpp: -------------------------------------------------------------------------------- 1 | #define MAXM 10 2 | #define MAXN 10 3 | int coin[MAXN]; 4 | long long make, dp[MAXN][MAXM]; 5 | 6 | /* If # of coins is un-changeable */ 7 | // top-down approach 8 | long long coinChange(int i, long long amount) { 9 | if(i >= MAXM) { 10 | return (0 == amount); 11 | } 12 | if(dp[i][amount] != -1) { 13 | return dp[i][amount]; 14 | } 15 | 16 | long long with = 0LL, without = 0LL; 17 | 18 | if(amount - coin[i] >= 0) { 19 | with = coinChange(i, amount - coin[i]); 20 | } 21 | 22 | without = coinChange(i + 1, amount); 23 | 24 | return dp[i][amount] = with + without; 25 | // return dp[i][amount] = ret1 | ret2; 26 | } 27 | 28 | 29 | // bottom-up approach 30 | long long dp[MAXM]; 31 | void solve(int n, int m) { 32 | dp[0] = 1; 33 | for(int i = 0; i < n; i++) { 34 | for(int j = m; j > 0; j--) { 35 | if(j - coins[i] >= 0) { 36 | dp[j] += dp[j - coins[i]]; 37 | } 38 | } 39 | } 40 | } 41 | 42 | /* for consecutive coin i.e. 1, 2, 3, 4, 5, 6.... this top-down approach suffices */ 43 | void solve() { 44 | memset(dp, 0, sizeof dp); 45 | cache[0] = 1; 46 | for(int i = 1; i <= MAXM; i++) { 47 | for(int j = i; j <= MAXM; j++) { 48 | dp[j] += dp[j - i]; 49 | } 50 | } 51 | } 52 | 53 | // coins can be taken multiple times 54 | // permutation not allowed 55 | void solve2(int n, int m) { 56 | dp[0] = 1; 57 | for(int i = 0; i < n; i++) { 58 | for(int j = 1; j <= m; j++) { 59 | if(j - coins[i] >= 0) { 60 | dp[j] += dp[j - coins[i]]; 61 | } 62 | } 63 | } 64 | } 65 | 66 | // coins can be taken multiple times 67 | // [2, 3] and [3, 2] both are counted 68 | void solve3(int n, int m) { 69 | dp[0] = 1; 70 | for(int i = 1; i <= m; i++) { 71 | for(int j = 0; j < n; j++) { 72 | if(i - coins[j] >= 0) { 73 | dp[i] += dp[i - coins[j]]; 74 | } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /algorithms/convex_hull_graham_scan.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Complexity: O(n) + O(nLogn) + O(n) 3 | **** geometry template required **** 4 | */ 5 | #define MAX 100001 6 | 7 | PointI points[MAX]; 8 | int N; // # of points 9 | 10 | // A globle point needed for sorting points with reference to the first point 11 | // Used in compare function of qsort() 12 | PointI p0; 13 | 14 | // A utility function to find next to top in a stack 15 | PointI nextToTop(stack &S) { 16 | PointI p = S.top(); 17 | S.pop(); 18 | PointI res = S.top(); 19 | S.push(p); 20 | return res; 21 | } 22 | 23 | // A function used by library function qsort() to sort an array of 24 | // points with respect to the first point 25 | int compare(const void *vp1, const void *vp2) { 26 | PointI *p1 = (PointI *)vp1; 27 | PointI *p2 = (PointI *)vp2; 28 | 29 | int side = getSide(p0, *p2, *p1); 30 | if (side == 0) 31 | return (dist(p0, *p2) >= dist(p0, *p1)) ? -1 : 1; 32 | 33 | return side; 34 | } 35 | 36 | // Prints convex hull of a set of n points. 37 | void convexHull() { 38 | // Find the bottommost point 39 | int Min = 0; 40 | for (int i = 1; i < N; i++) { 41 | // Pick the bottom-most or chose the left most point in case of tie 42 | if (cmpYX(points[i], points[Min])) 43 | Min = i; 44 | } 45 | 46 | // Place the bottom-most point at first position 47 | swap(points[0], points[Min]); 48 | 49 | // Sort N - 1 points with respect to the first point. A point p1 comes 50 | // before p2 in sorted ouput if p2 has larger polar angle (in 51 | // counterclockwise direction) than p1 52 | p0 = points[0]; 53 | qsort(&points[1], N - 1, sizeof(PointI), compare); 54 | 55 | // Create an empty stack and push first three points to it. 56 | stack S; 57 | S.push(points[0]); 58 | S.push(points[1]); 59 | S.push(points[2]); 60 | 61 | // Process remaining n-3 points 62 | for (int i = 3; i < N; i++) { 63 | // Keep removing top while the angle formed by points next-to-top, 64 | // top, and points[i] makes a non-left turn 65 | while (getSide(nextToTop(S), points[i], S.top()) != -1) 66 | S.pop(); 67 | S.push(points[i]); 68 | } 69 | 70 | // Now stack has the output points, print contents of stack 71 | while (!S.empty()) { 72 | PointI p = S.top(); 73 | cout << p << endl; 74 | S.pop(); 75 | } 76 | } -------------------------------------------------------------------------------- /algorithms/convex_hull_jarvis.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Complexity: Theta(m * n) 3 | where n is number of input points and m is number of output or hull points (m <= n). 4 | Worst case: O(n^2) 5 | **** geometry template required **** 6 | */ 7 | #define MAX 100001 8 | 9 | PointI points[MAX]; 10 | int N; // # of points 11 | void convexHull() { 12 | // there must be atleast 3 points 13 | assert(N >= 3); 14 | 15 | // Initialize Result 16 | int next[N]; 17 | fill(next, next + N, -1); 18 | 19 | // Find the leftmost point 20 | int l = 0; 21 | for (int i = 1; i < N; i++) 22 | if(cmp(points[i], points[l])) 23 | l = i; 24 | 25 | // Start from leftmost point, keep moving counterclockwise 26 | // until reach the start point again 27 | int p = l, q; 28 | do { 29 | // Search for a point 'q' such that orientation(p, q, i) is 30 | // counterclockwise for all points 'i' 31 | q = (p + 1) % N; 32 | for(int i = 0; i < N; i++) { 33 | if (ccw(points[p], points[q], points[i]) == -1) { 34 | q = i; 35 | } 36 | } 37 | 38 | next[p] = q; // Add q to result as a next point of p 39 | p = q; // Set p as q for next iteration 40 | } while (p != l); 41 | 42 | // Print Result 43 | for(int i = 0; i < N; i++) { 44 | if (next[i] != -1) { 45 | cout << points[i] << endl; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /algorithms/dearrangement.cpp: -------------------------------------------------------------------------------- 1 | int d(int n) { 2 | if(n == 2) return 1; 3 | if(n == 1) return 0; 4 | if(dp[n] != -1) return dp[n]; 5 | return dp[n] = (n - 1) * (d(n - 1) + d(n - 2)); 6 | } -------------------------------------------------------------------------------- /algorithms/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #define pii pair 2 | #define INF (1 << 30) 3 | class Compare { 4 | public: 5 | int operator() ( const pii& p1, const pii& p2 ) { 6 | return p1.second > p2.second; 7 | } 8 | 9 | }; 10 | 11 | #define MAX 100001 12 | 13 | priority_queue , vector >, Compare> q; 14 | vector < pair > adj[MAX + 1]; 15 | int dis[MAX + 1]; 16 | int N; 17 | 18 | void reset() { 19 | q = priority_queue , vector< pair >, Compare> (); 20 | for(int i = 0; i < MAX; ++i) { 21 | dis[i] = INF; 22 | } 23 | } 24 | 25 | int dijkstra(int &src, int &des) { 26 | reset(); 27 | dis[src] = 0; 28 | q.push({src, dis[src]}); 29 | while(!q.empty()) { 30 | int u = q.top().first; 31 | q.pop(); 32 | if(u == des) return dis[des]; 33 | for(int i = 0, n = (int)adj[u].size(); i < n; ++i) { 34 | int v = adj[u][i].first; 35 | int cost = adj[u][i].second; 36 | 37 | if(dis[v] > dis[u] + cost) { 38 | dis[v] = dis[u] + cost; 39 | q.push({v, dis[v]}); 40 | } 41 | } 42 | } 43 | return -1; 44 | } -------------------------------------------------------------------------------- /algorithms/double_hashing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Source: Zobayer Blog 3 | M > N and should be close, better both be primes. 4 | M should be as much large as possible, not exceeding array size. 5 | HKEY is the Hash function, change it if necessary. 6 | */ 7 | 8 | #define NIL -1 9 | #define M 1021 10 | #define N 1019 11 | #define HKEY(x, i) ((x) % M + (i) * (1 + (x) % N)) % M 12 | 13 | int a[M + 1]; 14 | 15 | inline int hash(int key) { 16 | int i = 0, j; 17 | do { 18 | j = HKEY(key, i); 19 | if(a[j] == NIL) { a[j] = key; return j; } 20 | i++; 21 | } while(i < M); 22 | return -1; 23 | } 24 | 25 | // key is encoded string(e.g. abc => 012, xyz => 232425) 26 | inline int find(int key) { 27 | int i = 0, j; 28 | do { 29 | j = HKEY(key, i); 30 | if(a[j] == key) return j; 31 | i++; 32 | } while(a[j] != NIL and i < M); 33 | return -1; 34 | } -------------------------------------------------------------------------------- /algorithms/edit_distance.cpp: -------------------------------------------------------------------------------- 1 | int EditDistanceDP(string const& X, string const& Y) { 2 | int lenX = (int)X.length(); 3 | int lenY = (int)Y.length(); 4 | vector > dp(lenX + 1, vector(lenY + 1, 0)); 5 | for(int i = 0; i <= lenX; i++) dp[i][0] = i; 6 | for(int i = 0; i <= lenY; i++) dp[0][i] = i; 7 | for(int i = 1; i <= lenX; i++) { 8 | for(int j = 1; j <= lenY; j++) { 9 | if (X[i - 1] == Y[j - 1]) { 10 | dp[i][j] = dp[i - 1][j - 1]; 11 | } else { 12 | dp[i][j] = min(dp[i - 1][j], min(dp[i][j - 1], dp[i - 1][j - 1])) + 1; 13 | } 14 | } 15 | } 16 | return dp[lenX][lenY]; 17 | } 18 | 19 | // Recursive implementation 20 | int EditDistanceRecursion( char *X, char *Y, int lenX, int lenY ) { 21 | // Base case 1: if both are empty string, no operation is needed 22 | if( lenX == 0 && lenY == 0 ) 23 | return 0; 24 | // Base case 2: if one of the two strings is empty, then operation needed is equal to other non-empty string length 25 | if( lenX == 0 ) 26 | return lenY; 27 | 28 | if( lenY == 0 ) 29 | return lenX; 30 | 31 | // deletion 32 | int left = EditDistanceRecursion(X, Y, lenX - 1, lenY) + 1; 33 | // insertion 34 | int right = EditDistanceRecursion(X, Y, lenX, lenY - 1) + 1; 35 | // substitution or nothing 36 | int corner = EditDistanceRecursion(X, Y, lenX - 1, lenY - 1) + (X[lenX - 1] != Y[lenY - 1]); 37 | 38 | return min(left, min(right, corner)); 39 | } -------------------------------------------------------------------------------- /algorithms/extended_euclid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Extended Euclid 3 | ax + by = gcd(a, b), find x and y 4 | answer ex(25, 18) = ((-5, 7), 1) as (-5) * 25 + 18 * 7 = 1 5 | */ 6 | void ex_gcd(int a, int b, int &d, int &x, int &y) { // ax + by = d( gcd(a, b) ) 7 | if(b == 0) { 8 | x = 1, y = 0, d = a; 9 | return; 10 | } 11 | int x1, y1; 12 | ex_gcd(b, a % b, d, x1, y1); 13 | x = y1; 14 | y = x1 - (a / b) * y1; 15 | } 16 | 17 | /* 18 | ax + by = c, find x and y 19 | i.e. 25x + 18y = 839 -> x = 17, y = 23 20 | */ 21 | void diophantine(int a, int b, int &d, int &x, int &y) { 22 | ex_gcd(a, b, d, x, y); 23 | x *= n / d, y *= n / d; 24 | a /= d, b /= d; 25 | int c = ceil(-(double) x / b), f = ceil((double) y / a); 26 | if(c < f) 27 | x += b * c, y -= a * c; 28 | else 29 | x += b * f, y -= a * f; 30 | } 31 | 32 | // Modular mutiplicative inverse using extended euclid 33 | // Time complexity: O(log(m)^2) 34 | int modInv(int a, int mod, int &d, int &x, int &y) { 35 | ex_gcd(a, m, d, x, y); 36 | if(d > 1) return 0; 37 | int ret = x % m; 38 | return (ret < 0 ? ret + mod : ret); 39 | } -------------------------------------------------------------------------------- /algorithms/factorial.cpp: -------------------------------------------------------------------------------- 1 | int fact[MAX]; 2 | int invFact[MAX]; 3 | 4 | // nCr = n!/(n - r)! * r! => fact[n] * invFact[r] * invFact[n - r] % mod 5 | void calcFact(int n, int Mod = 1000000007) { 6 | fact[0] = 1; 7 | for(int i = 1; i <= n; i++) { 8 | fact[i] = i * fact[i - 1] % mod; 9 | invFact[i] = modInv(fact[i], mod); 10 | } 11 | } -------------------------------------------------------------------------------- /algorithms/floyd_cycle_finding.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Complexity: O(mu + lambda) 3 | Space: O(1) 4 | mu is the smallest index i 5 | lambda(the loop length) is the smallest positive integer such that x(mu) = x(mu + lambda). 6 | */ 7 | 8 | pair floyd_cycle_finding(int (*f)(int), int x0) { 9 | // the main phase of the algorithm, finding a repetation x(i) = x(2i). hare's speed is 2 * tortoise's 10 | int tortoise = f(x0), hare = f(f(x0)); 11 | while( tortoise != hare ) { 12 | tortoise = f(tortoise); 13 | hare = f(f(hare)); 14 | } 15 | 16 | // find the position of mu, the hare and tortoise move at the same speed 17 | int mu = 0; 18 | hare = tortoise; 19 | tortoise = x0; 20 | while( tortoise != hare ) { 21 | tortoise = f(tortoise); 22 | hare = f(hare); 23 | ++mu; 24 | } 25 | 26 | // find the length of the shortest cycle starting from x(mu), hare moves, tortoise stays 27 | int lambda = 1; 28 | hare = f(tortoise); 29 | 30 | while( tortoise != hare ) { 31 | hare = f(hare); 32 | ++lambda; 33 | } 34 | 35 | return make_pair(mu, lambda); 36 | } 37 | /* 38 | Usage: 39 | int f(int x) { 40 | return (( Z * x + I ) % M); 41 | } 42 | pair ans = floyd_cycle_finding(&f, L); 43 | */ -------------------------------------------------------------------------------- /algorithms/floyd_warshall.cpp: -------------------------------------------------------------------------------- 1 | #define MAX 1000 2 | int dis[MAX][MAX]; 3 | int nxt[MAX][MAX]; 4 | int edges, vertices; 5 | /* 6 | Time: O(n^3) 7 | Space: O(n^2) 8 | */ 9 | void floyd_warshall() { 10 | memset(dis, INF, sizeof dis); 11 | int u, v, cost; 12 | for(int i = 0; i < edges; ++i) scanf("%d %d %d", &u, &v, &cost), dis[u][v] = cost; 13 | // next[i][j] = k; path from i to j, k is the next node 14 | for(int i = 0; i < vertices; ++i) { 15 | for(int j = 0; j < vertices; ++j) { 16 | nxt[i][j] = j; 17 | } 18 | } 19 | 20 | for(int k = 0; k < vertices; ++k) { 21 | for(int i = 0; i < vertices; ++i) { 22 | for(int j = 0; j < vertices; ++j) { 23 | if(dis[i][k] + dis[k][j] < dis[i][j]) { 24 | dis[i][j] = dis[i][k] + dis[k][j]; 25 | nxt[i][j] = nxt[i][k]; 26 | } 27 | } 28 | } 29 | } 30 | } 31 | 32 | void findPath(int src, int dest, vector& path) { 33 | path.push_back(src); 34 | int u = src; 35 | while(u != dest) { 36 | u = nxt[u][dest]; 37 | path.push_back(u); 38 | } 39 | } 40 | 41 | // mini-max 42 | /* 43 | for(int k = 0; k < vertices; ++k) 44 | for(int i = 0; i < vertices; ++i) 45 | for(int j = 0; j < vertices; ++j) 46 | dis[i][j] = min(dis[i][j], max(dis[i][k], dis[k][j])); 47 | */ 48 | 49 | // Transitive closure: if there is a direct/indirect path between i to j. input dis[u][v] = 1 if path else 0 (no need to assign cost) 50 | /* 51 | for(int k = 0; k < vertices; ++k) 52 | for(int i = 0; i < vertices; ++i) 53 | for(int j = 0; j < vertices; ++j) 54 | dis[i][j] = dis[i][j] | (dis[i][k] & dis[k][j]); 55 | */ -------------------------------------------------------------------------------- /algorithms/game_tree.cpp: -------------------------------------------------------------------------------- 1 | // game with n stones 2 | // In a single move, a player can remove either 2, 3 or 5 stones 3 | // Both players play optimally, player X will always play first 4 | // 2, 3 or 5 can be choosen multiple times 5 | void solve(int n) { // n stones 6 | vector dp(n + 1, 0); 7 | dp[0] = 0; // 0 means loosing position 8 | dp[1] = 0; 9 | dp[2] = 1; // 1 means winning position 10 | dp[3] = 1; 11 | dp[4] = 1; 12 | dp[5] = 1; 13 | for(int i = 6; i <= n; i++) { 14 | dp[i] = !dp[i - 2] or !dp[i - 3] or !dp[i - 5]; 15 | } 16 | return dp[n]; 17 | } 18 | 19 | /*** 20 | Two players are playing a game on a 15 x 15 chessboard. The rules of the game are as follows: 21 | 22 | The game starts with a single coin located at some coordinate. The coordinate of the upper left cell is [0, 0] 23 | and the coordinate of the lower right cell is [14, 14]. 24 | In each move, a player must move the coin from cell (x, y) to one of the following locations: 25 | 26 | x - 1, y - 2 27 | x + 1, y - 2 28 | x - 2, y + 1 29 | x - 2, y - 1 30 | 31 | Note: The coin must remain inside the confines of the board. 32 | 33 | The players move in alternating turns. The first player who is unable to make a move loses the game. 34 | ***/ 35 | 36 | vector dp; 37 | vector visited; 38 | 39 | bool solve(int x, int y) { 40 | if(x < 0 or y < 0 or x >= n and y >= n) { 41 | return true; 42 | } 43 | if(visited[x][y]) { 44 | return dp[x][y]; 45 | } 46 | bool ret = false; 47 | ret &= !solve(x - 1, y - 2); 48 | ret &= !solve(x + 1, y - 2); 49 | ret &= !solve(x - 2, y + 1); 50 | ret &= !solve(x - 2, y - 1); 51 | 52 | visited[x][y] = true; 53 | return dp[x][y] = ret; 54 | } 55 | 56 | 57 | // Given 'maxChoosableInteger', a player can choose any numbers from [1, 2 ...... maxChoosableInteger] 58 | // The first player who can cause the running total exceed or equal 'desiredTotal' will win 59 | // Each number can be used only once 60 | // Both players play optimally 61 | 62 | // utility function 63 | bool canIWin(int maxChoosableInteger, int desiredTotal, int mask, vector& visited, vector& dp) { 64 | if(desiredTotal <= 0) { 65 | return false; 66 | } 67 | if(visited[mask]) { 68 | return dp[mask]; 69 | } 70 | bool canWin = false; 71 | for(int i = 1; i <= maxChoosableInteger; i++) { 72 | if(!(mask & (1 << i))) { 73 | canWin |= !canIWin(maxChoosableInteger, desiredTotal - i, mask | (1 << i), visited, dp); 74 | if(canWin) { 75 | break; 76 | } 77 | } 78 | } 79 | visited[mask] = true; 80 | return dp[mask] = canWin; 81 | } 82 | 83 | bool canIWin(int maxChoosableInteger, int desiredTotal) { 84 | if(maxChoosableInteger >= desiredTotal) { 85 | return true; 86 | } 87 | int totalPossible = (maxChoosableInteger * (maxChoosableInteger + 1)) / 2; 88 | if(totalPossible < desiredTotal) { 89 | return false; 90 | } 91 | int mask = 0; 92 | const int maxMask = 1 << (maxChoosableInteger + 1); 93 | vector dp(maxMask, false); 94 | vector visited(maxMask, false); 95 | return canIWin(maxChoosableInteger, desiredTotal, mask, visited, dp); 96 | } -------------------------------------------------------------------------------- /algorithms/hackenbush.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | Alice and Bob are playing a game with a rooted tree. The tree has N vertices and the first node is 1, is always the root. 3 | Here are the basic rules: 4 | They move in alternating turns, and both players always move optimally. 5 | During each move, a player removes an edge from the tree, disconnecting one of its leaves or branches. 6 | The leaf or branch that was disconnected from the rooted tree is removed from the game. 7 | The first player to be unable to make a move loses the game. 8 | Alice always makes the first move. 9 | ***/ 10 | 11 | /*** 12 | Explanation: 13 | This is a Green Hackenbush problem. We consider it to be green because each edge can be removed by either player. Because we're working with a tree, we can also easily apply the colon principle. 14 | 15 | The colon principle states that, if a node is connected with n stalks of length l1, l2, l3....... ln - 1, then all of these stalks can be replaced with a single stalk of length l = l1 xor l2 xor l3 .... xor ln - 1. 16 | 17 | When using the colon principle on a tree, we can recursively convert the tree into a stalk. A stalk of length l is same as a single Nim pile of height l. This means that if we end up with a single Nim pile of positive height, Alice wins; otherwise, Bob wins. 18 | ***/ 19 | 20 | #define NODE 502 21 | vector adj[NODE + 10]; 22 | 23 | int hackenbush(int u, int parent) { 24 | 25 | int result = 0; 26 | for(int i = 0; i < adj[u].size(); i++) { 27 | int v = adj[u][i]; 28 | 29 | if (v == parent) continue; 30 | 31 | result ^= hackenbush (v, u) + 1; 32 | }; 33 | 34 | return result; 35 | } 36 | // int res = hackenbush (1, 0); 37 | // if ( res ) printf ( "Alice\n" ); 38 | // else printf ( "Bob\n" ); -------------------------------------------------------------------------------- /algorithms/hashmap.cpp: -------------------------------------------------------------------------------- 1 | template > 2 | class unordered_map : public HashTable {}; -------------------------------------------------------------------------------- /algorithms/hashset.cpp: -------------------------------------------------------------------------------- 1 | template > 2 | class unordered_set : public HashTable {}; -------------------------------------------------------------------------------- /algorithms/hashtable.cpp: -------------------------------------------------------------------------------- 1 | #ifndef HASH_TABLE_H 2 | #define HASH_TABLE_H 3 | 4 | #define TABLE_SIZE 100 5 | 6 | // Hash node class template 7 | template 8 | class HashNode { 9 | public: 10 | HashNode(const K &key, const V &value) 11 | : key(key) 12 | , value(value) 13 | , next(nullptr) { 14 | } 15 | 16 | K getKey() const { 17 | return key; 18 | } 19 | 20 | V& getValue() { 21 | return value; 22 | } 23 | 24 | V const& getValue() const { 25 | return value; 26 | } 27 | 28 | void setValue(V value) { 29 | HashNode::value = value; 30 | } 31 | 32 | HashNode *getNext() const { 33 | return next; 34 | } 35 | 36 | void setNext(HashNode *next) { 37 | HashNode::next = next; 38 | } 39 | private: 40 | // key-value pair 41 | K key; 42 | V value; 43 | // next bucket with the same key 44 | HashNode *next; 45 | }; 46 | 47 | // Default hash function class 48 | template 49 | struct KeyHash { 50 | unsigned long operator()(const K& key) const { 51 | return static_cast(key) % TABLE_SIZE; 52 | } 53 | }; 54 | 55 | // Hash map class template 56 | template > 57 | class HashTable { 58 | public: 59 | HashTable() { 60 | // construct zero initialized hash table of size 61 | table = new HashNode *[TABLE_SIZE](); 62 | elements = 0; 63 | } 64 | 65 | ~HashTable() { 66 | // destroy all buckets one by one 67 | for (int i = 0; i < TABLE_SIZE; ++i) { 68 | HashNode *entry = table[i]; 69 | while (entry != nullptr) { 70 | HashNode *prev = entry; 71 | entry = entry->getNext(); 72 | delete prev; 73 | } 74 | table[i] = nullptr; 75 | } 76 | // destroy the hash table 77 | delete [] table; 78 | } 79 | 80 | bool get(const K &key, V &value) { 81 | unsigned long hashValue = hashFunc(key); 82 | HashNode *entry = table[hashValue]; 83 | while (entry != NULL) { 84 | if (entry->getKey() == key) { 85 | value = entry->getValue(); 86 | return true; 87 | } 88 | entry = entry->getNext(); 89 | } 90 | return false; 91 | } 92 | 93 | void put(const K &key, const V &value) { 94 | unsigned long hashValue = hashFunc(key); 95 | HashNode *prev = nullptr; 96 | HashNode *entry = table[hashValue]; 97 | while (entry != nullptr and entry->getKey() != key) { 98 | prev = entry; 99 | entry = entry->getNext(); 100 | } 101 | if (entry == nullptr) { 102 | entry = new HashNode(key, value); 103 | if (prev == nullptr) { 104 | // insert as first bucket 105 | table[hashValue] = entry; 106 | } else { 107 | prev->setNext(entry); 108 | } 109 | ++elements; 110 | } else { 111 | // just update the value 112 | entry->setValue(value); 113 | } 114 | } 115 | 116 | V& operator [] (const K& key) { 117 | unsigned long hashValue = hashFunc(key); 118 | HashNode *entry = table[hashValue]; 119 | while (entry != NULL) { 120 | if (entry->getKey() == key) { 121 | return entry->getValue(); 122 | } 123 | entry = entry->getNext(); 124 | } 125 | // key is not found 126 | 127 | put(key, V{}); 128 | return (*this)[key]; 129 | } 130 | 131 | void remove(const K &key) { 132 | unsigned long hashValue = hashFunc(key); 133 | HashNode *prev = nullptr; 134 | HashNode *entry = table[hashValue]; 135 | while (entry != nullptr and entry->getKey() != key) { 136 | prev = entry; 137 | entry = entry->getNext(); 138 | } 139 | if (entry != nullptr) { 140 | if (prev == nullptr) { 141 | // remove first bucket of the list 142 | table[hashValue] = entry->getNext(); 143 | } else { 144 | prev->setNext(entry->getNext()); 145 | } 146 | --elements; 147 | delete entry; 148 | } 149 | } 150 | 151 | V& insert(K const& key) { 152 | put(key, V{}); 153 | return (*this)[key]; 154 | } 155 | 156 | size_t size() const { 157 | return elements; 158 | } 159 | 160 | private: 161 | // hash table 162 | HashNode **table; 163 | F hashFunc; 164 | size_t elements; 165 | }; 166 | 167 | #endif // HASH_TABLE_H -------------------------------------------------------------------------------- /algorithms/heap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Details: Jane Alam Jan LightOj Tutorial 3 | Usage: 4 | heap Heap; 5 | Heap.clear(); 6 | Heap.insert(value); 7 | Heap.remove(); 8 | Heap.print(); 9 | */ 10 | struct heap { 11 | int myarray[NN+1]; // myarray to store the numbers as heap, 1 indexed 12 | int n; // the number of nodes in my array 13 | heap() { // constructor 14 | clear(); // we clear the heap 15 | } 16 | void clear() { // initialize the heap 17 | n = 0; // initially there are no nodes in the heap 18 | } 19 | void insert( int K ) { // inserting an element K in the heap 20 | if( n == NN ) { // the heap is full 21 | printf("cannot insert any more element, the heap is full\n"); 22 | return; 23 | } 24 | ++n; // so, we have a new element, we increased n before adding 25 | // the element because we start from index 1 26 | myarray[n] = K; // inserted the element at the rightmost position 27 | int p = n; // for keeping the current position 28 | while( p > 1 ) { // p = 1 means we are on the root, and its a heap 29 | int pr = p / 2; // pr is the parent of p 30 | if( myarray[pr] > myarray[p] ) { // parent is greater than child 31 | swap( myarray[pr], myarray[p] ); 32 | p = pr; // now the new position of the current element is pr 33 | } else break; // otherwise its a heap, so we can stop here 34 | } 35 | } 36 | int remove() { // removing the minimum element from the heap 37 | if( n == 0 ) { // is the heap is empty 38 | printf("The heap is empty, cannot delete.\n"); 39 | return -1; 40 | } 41 | int K = myarray[1]; // first element in the heap is the minimum 42 | myarray[1] = myarray[n]; // brought the last element in 1st position 43 | n--; // as we removed one element, now we need to maintain the heap 44 | 45 | int p = 1; // as we moved the rightmost element in index 1 46 | while( 2 * p <= n ) { // means p has at least one child, if 2*p > n 47 | // we are sure that p is in the last level 48 | int ch = 2 * p; // contains the index of the child 49 | if( 2 * p + 1 <= n ) { // right child exists 50 | if( myarray[ch] > myarray[ch+1] ) // right child is smaller 51 | // than left child 52 | ch++; // ch contains the index of the right child 53 | } 54 | if( myarray[p] > myarray[ch] ) { // so, current node is larger 55 | // than its child 56 | swap( myarray[p], myarray[ch] ); 57 | p = ch; // new position of the current element 58 | } else break; //current node is smaller than its children, so heap 59 | } 60 | return K; // as we stored the minimum element in K 61 | } 62 | 63 | void print() { // printing the heap 64 | printf("Number of elements: %d\n", n); 65 | for( int i = 1; i <= n; i++ ) printf("%d ", myarray[i]); 66 | printf("\n"); 67 | } 68 | 69 | // Time: O(nlogn) 70 | // Extra space: O(1) as we will pass the input array as res here 71 | void heapSort(int* res) { 72 | for(int i = 0, len = n; i < len; ++i) { 73 | res[i] = remove(); 74 | } 75 | } 76 | }; -------------------------------------------------------------------------------- /algorithms/heap_sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Details: Jane Alam Jan LightOj Tutorial 3 | Usage: 4 | heap Heap; 5 | Heap.clear(); 6 | Heap.insert(value); 7 | Heap.remove(); 8 | Heap.print(); 9 | */ 10 | struct heap { // minHeap 11 | vector data; // data to store the numbers as heap, 1 indexed 12 | int capacity; 13 | int n; // the number of nodes in my array 14 | heap(int _size) { // constructor 15 | capacity = _size; 16 | data = vector(capacity); 17 | clear(); // we clear the heap 18 | } 19 | void clear() { // initialize the heap 20 | n = 0; // initially there are no nodes in the heap 21 | } 22 | void insert( int K) { // inserting an element K in the heap 23 | if( n == capacity) { // the heap is full 24 | printf("cannot insert any more element, the heap is full\n"); 25 | return; 26 | } 27 | ++n; // so, we have a new element, we increased n before adding 28 | // the element because we start from index 1 29 | data[n] = K; // inserted the element at the rightmost position 30 | int p = n; // for keeping the current position 31 | while( p > 1 ) { // p = 1 means we are on the root, and its a heap 32 | int pr = p / 2; // pr is the parent of p 33 | if( data[pr] > data[p] ) { // parent is greater than child 34 | swap( data[pr], data[p] ); 35 | p = pr; // now the new position of the current element is pr 36 | } else break; // otherwise its a heap, so we can stop here 37 | } 38 | } 39 | int remove() { // removing the minimum element from the heap 40 | if( n == 0 ) { // is the heap is empty 41 | printf("The heap is empty, cannot delete.\n"); 42 | return -1; 43 | } 44 | int K = data[1]; // first element in the heap is the minimum 45 | data[1] = data[n]; // brought the last element in 1st position 46 | n--; // as we removed one element, now we need to maintain the heap 47 | 48 | int p = 1; // as we moved the rightmost element in index 1 49 | while( 2 * p <= n ) { // means p has at least one child, if 2*p > n 50 | // we are sure that p is in the last level 51 | int ch = 2 * p; // contains the index of the child 52 | if( 2 * p + 1 <= n ) { // right child exists 53 | if( data[ch] > data[ch+1] ) // right child is smaller 54 | // than left child 55 | ch++; // ch contains the index of the right child 56 | } 57 | if( data[p] > data[ch] ) { // so, current node is larger 58 | // than its child 59 | swap( data[p], data[ch] ); 60 | p = ch; // new position of the current element 61 | } else break; //current node is smaller than its children, so heap 62 | } 63 | return K; // as we stored the minimum element in K 64 | } 65 | 66 | void print() { // printing the heap 67 | printf("Number of elements: %d\n", n); 68 | for( int i = 1; i <= n; i++ ) printf("%d ", data[i]); 69 | printf("\n"); 70 | } 71 | 72 | // Time: O(nlogn) 73 | // Extra space: O(1) as we will pass the input array as res here 74 | void heapSort(vector& result) { 75 | for(int i = 0, len = n; i < len; ++i) { 76 | result[i] = remove(); 77 | } 78 | } 79 | }; -------------------------------------------------------------------------------- /algorithms/kadane.cpp: -------------------------------------------------------------------------------- 1 | // maximum contiguous sum of an array 2 | int kadane(vector& arr, int& left, int& right) { 3 | int result = INT_MIN, currSum = 0; 4 | int n = (int)arr.size(); 5 | left = 0; 6 | for(int i = 0; i < n; i++) { 7 | currSum += arr[i]; 8 | 9 | if(currSum < 0) { 10 | currSum = 0; 11 | left = i + 1; 12 | } 13 | 14 | if(currSum > result) { 15 | right = i; 16 | result = currSum; 17 | } 18 | } 19 | return result; 20 | } 21 | 22 | 23 | // Find Maximum subarray sum in O(n^3) using Kadane algorithm 24 | void findMaxSum(vector>& M) { 25 | // Variables to store the final output 26 | int maxSum = INT_MIN, finalLeft, finalRight, finalTop, finalBottom; 27 | int m = (int)M.size(); 28 | int n = (int)M[0].size(); 29 | int left, right, i; 30 | int sum, start, finish; 31 | vector tmp(m); 32 | 33 | // Set the left column 34 | for (left = 0; left < n; ++left) { 35 | // Initialize all elements of temp as 0 36 | memset(tmp, 0, sizeof(tmp)); 37 | 38 | // Set the right column for the left column set by outer loop 39 | for (right = left; right < n; ++right) { 40 | // Calculate sum between current left and right for every row 'i' 41 | for (i = 0; i < m; ++i) { 42 | tmp[i] += M[i][right]; 43 | } 44 | 45 | // Find the maximum sum subarray in temp[]. The kadane() function 46 | // also sets values of start and finish. So 'sum' is sum of 47 | // rectangle between (start, left) and (finish, right) which is the 48 | // maximum sum with boundary columns strictly as left and right. 49 | sum = kadane(tmp, start, finish); 50 | 51 | // Compare sum with maximum sum so far. If sum is more, then update 52 | // maxSum and other output values 53 | if (sum > maxSum) { 54 | maxSum = sum; 55 | finalLeft = left; 56 | finalRight = right; 57 | finalTop = start; 58 | finalBottom = finish; 59 | } 60 | } 61 | } 62 | 63 | // Print final values 64 | printf("(Top, Left) (%d, %d)\n", finalTop, finalLeft); 65 | printf("(Bottom, Right) (%d, %d)\n", finalBottom, finalRight); 66 | printf("Max sum is: %d\n", maxSum); 67 | } -------------------------------------------------------------------------------- /algorithms/kmp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The position of the text character compared can increase at most length(text)-1 times, the position of the first pattern character can increase at most length(text) - length(pattern) times, so the algorithm takes at most 2*length(text) - length(pattern) - 1 steps. 3 | 4 | The preprocessing (construction of the border table) takes at most 2*length(pattern) steps, thus the overall complexity is O(m+n) and no more m + 2*n steps are executed if m is the length of the pattern and n the length of the text. 5 | */ 6 | void computeLPSArray(char *pat, int M, int *lps); 7 | 8 | void KMPSearch(char *pat, char *txt) { 9 | int M = strlen(pat); 10 | int N = strlen(txt); 11 | 12 | // create lps[] that will hold the longest prefix suffix values for pattern 13 | int *lps = (int *) malloc(sizeof(int) * M); 14 | int j = 0; // index for pat[] 15 | 16 | // Preprocess the pattern (calculate lps[] array) 17 | computeLPSArray(pat, M, lps); 18 | 19 | int i = 0; // index for txt[] 20 | while(i < N) { 21 | if(pat[j] == txt[i]) { 22 | j++; 23 | i++; 24 | } 25 | 26 | if (j == M) { 27 | printf("Found pattern at index %d \n", i - j); 28 | j = lps[j - 1]; 29 | } 30 | 31 | // mismatch after j matches 32 | else if(pat[j] != txt[i]) { 33 | // Do not match lps[0..lps[j - 1]] characters, 34 | // they will match anyway 35 | if(j != 0) 36 | j = lps[j - 1]; 37 | else 38 | i++; 39 | } 40 | } 41 | free(lps); // to avoid memory leak 42 | } 43 | 44 | void computeLPSArray(char *pat, int M, int *lps) { 45 | int len = 0; // lenght of the previous longest prefix suffix 46 | int i; 47 | 48 | lps[0] = 0; // lps[0] is always 0 49 | i = 1; 50 | 51 | // the loop calculates lps[i] for i = 1 to M - 1 52 | while(i < M) { 53 | if(pat[i] == pat[len]) { 54 | lps[i++] = ++len; 55 | } else { // (pat[i] != pat[len]) 56 | if( len != 0 ) { 57 | // This is tricky. Consider the example AAACAAAA and i = 7. 58 | len = lps[len - 1]; 59 | // Also, note that we do not increment i here 60 | } else { // if (len == 0) 61 | lps[i++] = 0; 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /algorithms/knapsack.cpp: -------------------------------------------------------------------------------- 1 | // classic knapsack problem. 2 | #define MAXN 100 3 | #define MAXW 1000 4 | int n; 5 | int dp[MAXN + 1][MAXW + 1]; 6 | int weight[MAXN + 1]; 7 | int price[MAXN + 1]; 8 | int capacity; 9 | 10 | // top down approach 11 | int knapsack(int i, int w) { 12 | if(i == n) { 13 | return 0; 14 | } 15 | if(dp[i][w] != -1) { 16 | return dp[i][w]; 17 | } 18 | int profit1 = 0, profit2 = 0; 19 | if(w + weight[i] <= capacity) { 20 | profit1 = price[i] + knapsack(i + 1, w + weight[i]); 21 | } 22 | 23 | profit2 = knapsack(i + 1, w); 24 | 25 | return dp[i][w] = max(profit1, profit2); 26 | } 27 | 28 | // bottom up approach (better approach) 29 | int dp[MAXW + 1]; 30 | void solve(int n, int capacity) { 31 | for (int i = 0; i < n; i++) { 32 | for (int j = capacity; j >= 0; j--) { 33 | if(weight[i] <= j) { 34 | dp[j] = max(dp[j], dp[j - weight[i]] + price[i]); 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /algorithms/kruskal.cpp: -------------------------------------------------------------------------------- 1 | #define MAX 100001 2 | struct kruskal { 3 | int u, v, cost; 4 | kruskal() {} 5 | kruskal(int a, int b, int c): u(a), v(b), cost(c) { 6 | } 7 | bool operator < (const kruskal& other) const { 8 | return cost < other.cost; 9 | } 10 | } g[MAX]; 11 | 12 | // Union-find Disjoint-Set Utility Functions 13 | vector pset; 14 | void initSet(int _size) { 15 | pset.resize(_size); 16 | for(int i = 0; i < _size; ++i) pset[i] = i; 17 | } 18 | int findSet(int i) { 19 | return (pset[i] == i) ? i : (pset[i] = findSet(pset[i])); 20 | } 21 | void unionSet(int i, int j) { 22 | pset[findSet(i)] = findSet(j); 23 | } 24 | bool isSameSet(int i, int j) { 25 | return findSet(i) == findSet(j); 26 | } 27 | 28 | int mst(int edgeN, int vertexN) { 29 | int sum = 0, a, b, c; 30 | for(int i = 0; i < edgeN; i++) { 31 | scanf("%d %d %d", &a, &b, &c); 32 | g[i] = kruskal(a, b, c); 33 | } 34 | initSet(vertexN + 1); 35 | sort(g, g + edgeN); 36 | for(int i = 0; i < edgeN; ++i) { 37 | if(!isSameSet(g[i].u, g[i].v)) { 38 | sum += g[i].cost; 39 | unionSet(g[i].u, g[i].v); 40 | } 41 | } 42 | return sum; 43 | } -------------------------------------------------------------------------------- /algorithms/lca.cpp: -------------------------------------------------------------------------------- 1 | // LCA without sparse table 2 | int lca(int u, int v) { 3 | if(depth[u] > depth[v]) { 4 | swap(u, v); 5 | } 6 | while(depth[v] > depth[u]) { 7 | v = parent[v]; 8 | } 9 | // assert(depth[v] == depth[u]); 10 | while(u != v) { 11 | u = parent[u], v = parent[v]; 12 | } 13 | // assert(u == v); 14 | 15 | return u; 16 | } 17 | 18 | //LCA using sparse table 19 | //Complexity: O(NlgN, lgN) 20 | #define Max 100005 21 | int depth[Max]; 22 | int table[Max][22]; // sparse table. there will be n rows for n nodes and logn columns for every node. pre-processing complexity O(nlogn) and Query complexity logn. table[i][j] holds 2^j th parent of ith node. 23 | int parent[Max]; 24 | vector adj[Max]; 25 | void dfs(int from, int u, int dep) { 26 | parent[u] = from; 27 | depth[u] = dep; 28 | for(int i = 0; i < (int)adj[u].size(); i++) { 29 | int v = adj[u][i]; 30 | if(v == from) continue; 31 | dfs(u, v, dep + 1); 32 | } 33 | } 34 | 35 | void lcaInit(int N) { 36 | memset(table, -1, sizeof table); 37 | for(int i = 0; i < N; i++) { 38 | table[i][0] = parent[i]; 39 | } 40 | 41 | for (int j = 1; (1 << j) < N; j++) { 42 | for(int i = 0; i < N; i++) { 43 | if (table[i][j - 1] != -1) { 44 | table[i][j] = table[table[i][j - 1]][j - 1]; 45 | } 46 | } 47 | } 48 | } 49 | 50 | int lcaQuery(int p, int q) { 51 | if(depth[p] < depth[q]) { 52 | swap(p, q); 53 | } 54 | 55 | // building log's value 56 | int log = 1; 57 | while(true) { 58 | int next = log + 1; 59 | if((1 << next) > depth[p]) break; 60 | log++; 61 | } 62 | 63 | // uplifting p at the same level of q 64 | for(int i = log; i >= 0; i--) { 65 | if (depth[p] - (1 << i) >= depth[q]) { 66 | p = table[p][i]; 67 | } 68 | } 69 | 70 | if (p == q) return p; 71 | 72 | // uplifting p and q untill both of their parents are same and we're in root 73 | for(int i = log; i >= 0; i--) { 74 | if (table[p][i] != -1 and table[p][i] != table[q][i]) { 75 | p = table[p][i]; 76 | q = table[q][i]; 77 | } 78 | } 79 | 80 | // when p and q are in the same level, return one of their parent 81 | return parent[p]; 82 | } 83 | /* 84 | dfs(0, 0, 0); 85 | lcaInit(n); 86 | println(lcaQuery(u, v)); 87 | */ -------------------------------------------------------------------------------- /algorithms/lcp.cpp: -------------------------------------------------------------------------------- 1 | int LCS(string const& sA, string const& sB) { 2 | int lenA = (int)sA.length(); 3 | int lenB = (int)sB.length(); 4 | vector > dp(lenA + 1, vector(lenB + 1, 0)); 5 | for(int i = 0; i <= lenA; i++) dp[i][0] = 0; 6 | for(int i = 0; i <= lenB; i++) dp[0][i] = 0; 7 | for(int i = 1; i <= lenA; i++) { 8 | for(int j = 1; j <= lenB; j++) { 9 | if(sA[i - 1] == sB[j - 1]) { 10 | dp[i][j] = dp[i - 1][j - 1] + 1; 11 | } else { 12 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 13 | } 14 | } 15 | } 16 | return dp[lenA][lenB]; 17 | } -------------------------------------------------------------------------------- /algorithms/lis.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define MAX 100 3 | int dp[MAX]; 4 | //int x[] = {-7, 10, 9, 2, 3, 8, 8, 1}; 5 | //int x[] = {389, 207, 155, 300, 299, 170, 158, 65}; 6 | int x[] = {1, 2, 3, 4, 5, 4, 3, 2, 1, 10}; 7 | int N = (sizeof x / sizeof(int)) - 1; 8 | void _reset() { 9 | memset(dp, -1, sizeof dp); 10 | } 11 | 12 | /** 13 | Index value of longest increasing subsequence in O(n^2) - Recursively with dp apporoach. 14 | Ultimately this recursive approach is not better than iterative as 15 | all sub problems are revisited. 16 | **/ 17 | int LIS(int i) { 18 | if(i == 0) return 1; 19 | if (dp[i] != -1) { 20 | return dp[i]; 21 | } 22 | int ans = 1; 23 | for(int j = 0; j < i; j++) { 24 | if (x[i] > x[j]) { 25 | ans = max(ans, 1 + LIS(j)); 26 | } 27 | } 28 | return dp[i] = ans; 29 | } 30 | 31 | 32 | /** 33 | Longest Increasing Subsequence Length of full array in O(n^2) - Iteratively with dp apporoach. 34 | **/ 35 | 36 | int pos; 37 | int LIS() { 38 | _reset(); 39 | dp[0] = 1; 40 | 41 | for(int i = 1; i <= N; i++) { 42 | int ans = 1; 43 | for(int j = 0; j < i; j++) { 44 | if(x[i] > x[j]) { 45 | ans = max(ans, 1 + dp[j]); 46 | } 47 | } 48 | dp[i] = ans; 49 | } 50 | 51 | int lis = 0; 52 | for(int i = 0; i <= N; i++) { 53 | if(dp[i] > lis) { 54 | lis = dp[i]; 55 | pos = i; // track the last index of LIS (required to construct sequence) 56 | } 57 | } 58 | return lis; 59 | } 60 | 61 | /** 62 | Finding the sequence of LIS 63 | **/ 64 | vector listSequence; 65 | void sequence() { 66 | listSequence.clear(); 67 | listSequence.push_back(x[pos]); 68 | for(int i = pos-1; i >= 0; i--) { 69 | if( x[i] < x[pos] && dp[i] == dp[pos] -1) { 70 | pos = i; 71 | listSequence.push_back(x[i]); 72 | } 73 | } 74 | for(int i = listSequence.size() -1; i >= 0; i--) cout << listSequence[i] << " "; 75 | } 76 | 77 | /** 78 | Longest Increasing Subsequence in O(nlogk) time 79 | Jane Alam Jan tutorial 80 | **/ 81 | int I[30]; 82 | int LisNlogk() { 83 | int i; 84 | memset(I, INT_MAX, sizeof I); 85 | I[0] = INT_MIN; 86 | 87 | int trackPosition = 0; 88 | int max = INT_MIN; 89 | for(i = 0; i <= N; i++ ) { 90 | int begin, end, mid; 91 | begin = 0; 92 | end = trackPosition; 93 | while( begin <= end ) { 94 | mid = ( begin + end ) / 2; 95 | if( I[mid] < x[i] ) 96 | begin = mid + 1; 97 | else 98 | end = mid - 1; 99 | } 100 | // observe the binary search carefully, when the binary search ends 101 | // begin > end and we put our item in I[begin] 102 | I[begin] = x[i]; 103 | dp[i] = begin; // storing the LIS of every position 104 | if(dp[i] > max) { // track the last index for later reconstruct the sequence 105 | max = dp[i]; 106 | pos = i; 107 | } 108 | if( trackPosition < begin ) 109 | trackPosition = begin; 110 | } 111 | return trackPosition; 112 | } 113 | 114 | int LdsNlogk() { 115 | // LDS can also be achieved by recersing the data array and then calculating LIS 116 | int i; 117 | memset(I, INT_MIN, sizeof I); 118 | I[0] = INT_MAX; 119 | 120 | int trackPosition = 0; 121 | int Max = INT_MIN; 122 | for(i = 0; i <= N; i++ ) { 123 | int begin, end, mid; 124 | begin = 0; 125 | end = trackPosition; 126 | while( begin <= end ) { 127 | mid = ( begin + end ) / 2; 128 | if( I[mid] > x[i] ) 129 | begin = mid + 1; 130 | else 131 | end = mid - 1; 132 | } 133 | // observe the binary search carefully, when the binary search ends 134 | // begin > end and we put our item in I[begin] 135 | I[begin] = x[i]; 136 | dp[i] = begin; // storing the LIS of every position 137 | if(dp[i] > Max) { // track the last index for later reconstruct the sequence 138 | Max = dp[i]; 139 | pos = i; 140 | } 141 | if( trackPosition < begin ) 142 | trackPosition = begin; 143 | } 144 | return trackPosition; 145 | } 146 | 147 | void decreasingSeq() { 148 | listSequence.clear(); 149 | listSequence.push_back(x[pos]); 150 | for(int i = pos-1; i >= 0; i--) { 151 | if( x[i] > x[pos] && dp[i] == dp[pos] - 1) { 152 | pos = i; 153 | listSequence.push_back(x[i]); 154 | } 155 | } 156 | for(int i = listSequence.size() -1; i >= 0; i--) cout << listSequence[i] << " "; 157 | } -------------------------------------------------------------------------------- /algorithms/lps.cpp: -------------------------------------------------------------------------------- 1 | // Returns the length of the longest palindromic subsequence in seq 2 | int lps(string const& s) { 3 | int n = (int)s.length(); 4 | // Strings of length 1 are palindrome of length 1 5 | vector> dp(n, vector(n, 0)); 6 | for(int i = 0; i < n; i++) dp[i][i] = 1; 7 | 8 | /* Build the table. Note that the lower diagonal values of table are 9 | useless and not filled in the process. The values are filled in a 10 | manner similar to MCM. */ 11 | for(int len = 2; len <= n; len++) { 12 | for (int i = 0; i < n - len + 1; i++) { 13 | int j = i + len - 1; 14 | if (s[i] == s[j] and len == 2) { 15 | dp[i][j] = 2; 16 | } 17 | else if (s[i] == s[j]) { 18 | dp[i][j] = dp[i + 1][j - 1] + 2; 19 | } 20 | else { 21 | dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]); 22 | } 23 | } 24 | } 25 | 26 | return dp[0][n - 1]; 27 | } -------------------------------------------------------------------------------- /algorithms/map_hashing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | hash() takes the string and next free index as parameter. 3 | if string is found in map, it returns its index. 4 | else, it inserts in current free index and updates the free index. 5 | */ 6 | 7 | map Map; 8 | 9 | inline int hashString(string const& s, int &n) { 10 | int ret; 11 | auto it = Map.find(s); 12 | if(it == Map.end()) Map.insert(pair< string, int > (s, ret = n++)); 13 | else ret = it->second; 14 | return ret; 15 | } -------------------------------------------------------------------------------- /algorithms/matrix_exp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Usage: 3 | i.e. 4 | f(n) = f(n - 1) + f(n - 2) for n > 1 5 | = a for n = 0 6 | = b for n = 1 7 | 8 | __ __ __ __ ^ (n - 1) __ 9 | | f(n) | | 1 1 | | b | 10 | | | = | | * | | 11 | | f(n - 1) | | 1 0 | | a | 12 | |__ __| |__ __| |__ | 13 | 14 | code: 15 | matrix mat; 16 | mat.row = mat.col = 2; 17 | mat.v[0][0] = mat.v[0][1] = mat.v[1][0] = 1; 18 | mat.v[1][1] = 0; 19 | if (n < 3) { 20 | if (n == 0) println(a); 21 | if (n == 1) println(b); 22 | if (n == 2) println(a + b); 23 | } else { 24 | mat = power(mat, n - 1); 25 | int ans = b * mat.v[0][0] + a * mat.v[0][1]; 26 | println(ans); 27 | } 28 | */ 29 | 30 | struct matrix { 31 | int v[Max][Max]; 32 | int row, col; 33 | }; 34 | 35 | matrix multiply(matrix &a, matrix &b) { 36 | assert(a.col == b.row); 37 | matrix r; 38 | r.row = a.row; 39 | r.col = b.col; 40 | rep(i, r.row) { 41 | rep(j, r.col) { 42 | int sum = 0; 43 | rep(k, a.col) { 44 | sum += a.v[i][k] * b.v[k][j]; 45 | sum %= Mod; 46 | } 47 | r.v[i][j] = sum; 48 | } 49 | } 50 | return r; 51 | } 52 | 53 | /* 54 | // possibility of stack overflow 55 | matrix power(matrix mat, int p) { 56 | assert(p >= 1); 57 | if (p == 1) return mat; 58 | if (p % 2 == 1) 59 | return multiply(mat, power(mat, p - 1)); 60 | matrix ret = power(mat, p / 2); 61 | ret = multiply(ret, ret); 62 | return ret; 63 | } 64 | */ 65 | 66 | void binary(int p, string &ret) { 67 | while (p > 0) { 68 | ret += (p % 2 == 0) ? "0" : "1"; 69 | p /= 2; 70 | } 71 | reverse(ret.begin(), ret.end()); 72 | } 73 | 74 | matrix power(matrix mat, int p) { 75 | string bin; 76 | binary(p, bin); 77 | matrix ret = mat; 78 | for (int i = 1; i < bin.size(); i++) { 79 | ret = multiply(ret, ret); 80 | if (bin[i] == '1') { 81 | ret = multiply(ret, mat); 82 | } 83 | } 84 | return ret; 85 | } -------------------------------------------------------------------------------- /algorithms/max_flow.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Complexity: O(V * E^2) 3 | */ 4 | #define MAX 100001 5 | #define INF (1 << 30) 6 | vector adj[MAX]; 7 | bool visited[MAX]; 8 | int flow[MAX][MAX]; 9 | int par[MAX]; 10 | int src, dest; 11 | int f; 12 | void augmentPath(int v, int minEdge) { 13 | if(v == src) { 14 | f = minEdge; 15 | return; 16 | } else if(visited[v]) { 17 | augmentPath(par[v], min(minEdge, flow[par[v]][v])); 18 | // update residue network 19 | flow[par[v]][v] -= f; // main flow 20 | flow[v][par[v]] += f; // reverse flow 21 | } 22 | } 23 | 24 | int EdmonMaxFlow() { 25 | int maxFlow = 0; 26 | memset(par, 0, sizeof par); 27 | // run BFS from source to destination and construct a path until flow = 0 28 | while(true) { // O(V) 29 | f = 0; 30 | memset(visited, false, sizeof visited); 31 | queue< int > q; 32 | q.push(src), visited[src] = true; 33 | 34 | while(!q.empty()) { // O(E) 35 | int v, u = q.front(); q.pop(); 36 | if(u == dest) break; 37 | 38 | for(int i = 0; i < (int)adj[u].size(); i++) { 39 | v = adj[u][i]; 40 | if(!visited[v] and flow[u][v] > 0) { 41 | visited[v] = true, par[v] = u; 42 | q.push(v); 43 | } 44 | } 45 | 46 | } 47 | // O(E) 48 | augmentPath(dest, INF); // updating the residue network. 49 | if(f == 0) break; // flow zero so no new flow is possible 50 | maxFlow += f; 51 | } 52 | return maxFlow; 53 | } 54 | -------------------------------------------------------------------------------- /algorithms/maximum_bipartite_matching.cpp: -------------------------------------------------------------------------------- 1 | // Maximum Bipartite matching using Edmond Karp maximum flow problem 2 | #define MAX 1005 3 | 4 | vector> adj[MAX]; // adj[u] = {{v1, capacity1}, {v2, capacity2}} 5 | vector residual[MAX]; // residual[u][v1] = capacity1 6 | int parent[MAX]; 7 | bool visited[MAX]; 8 | int n; 9 | 10 | /* Returns true if there is a path from 'src' to 'sink' in 11 | residual graph. Also fills parent[] to store the path */ 12 | bool bfs(int src, int sink) { 13 | memset(visited, false, sizeof visited); 14 | queue q; 15 | q.push(src); 16 | visited[src] = true; 17 | parent[src] = -1; 18 | 19 | while (!q.empty()) { 20 | int u = q.front(); 21 | q.pop(); 22 | for(int i = 0; i < (int)adj[u].size(); i++) { 23 | int v = adj[u][i].first; 24 | if(!visited[v] and residual[u][v] > 0) { 25 | q.push(v); 26 | parent[v] = u; 27 | visited[v] = true; 28 | } 29 | } 30 | } 31 | 32 | // If we reached sink in BFS starting from source, then return true, else false 33 | return visited[sink]; 34 | } 35 | 36 | int edmondKarp(int src, int sink) { 37 | int maxFlow = 0; 38 | for(int u = 0; u < n; u++) { 39 | residual[u].resize(n); 40 | for(int i = 0; i < (int)adj[u].size(); i++) { 41 | int v = adj[u][i].first; 42 | int capacity = adj[u][i].second; 43 | residual[u][v] = capacity; 44 | } 45 | } 46 | while(bfs(src, sink)) { 47 | int pathFlow = INT_MAX; 48 | // trace augmenting path 49 | int v = sink; 50 | while(v != src) { 51 | int u = parent[v]; 52 | pathFlow = min(pathFlow, residual[u][v]); 53 | v = u; 54 | } 55 | 56 | // update residual graph 57 | v = sink; 58 | while(v != src) { 59 | int u = parent[v]; 60 | residual[u][v] -= pathFlow; 61 | residual[v][u] += pathFlow; 62 | v = u; 63 | } 64 | 65 | maxFlow += pathFlow; 66 | } 67 | 68 | return maxFlow; 69 | } 70 | 71 | /* 72 | There are M job applicants and N jobs. Each applicant has a subset of jobs that he/she is interested in. 73 | Each job opening can only accept one applicant and a job applicant can be appointed for only one job. 74 | Find an assignment of jobs to applicants in such that as many applicants as possible get jobs. 75 | */ 76 | // Create a flow network before where there is an edge with capacity 1 from each applicants to 77 | // to each of his/her preferred jobs 78 | // i.e. adj[i].push_back({j, 1}) 79 | int maxBPM(int N, int M) { 80 | // create two new nodes 'src' and 'sink' 81 | int src = N + M; 82 | int sink = N + M + 1; 83 | 84 | // total nodes = total nodes of bipartite graph + two extra nodes(source and sink) 85 | n = N + M + 2; 86 | 87 | // add edge with capacity of 1 unit from src to each applicants node 88 | for(int i = 0; i < N; i++) { 89 | adj[src].push_back({i, 1}); 90 | } 91 | 92 | // add edge with capacity of 1 unit from each jobs node to sink 93 | for(int i = N; i < N + M; i++) { 94 | adj[i].push_back({sink, 1}); 95 | } 96 | 97 | // Now the maximum flow from src to sink is the maximum matching of bipartite graph 98 | return edmondKarp(src, sink); 99 | } -------------------------------------------------------------------------------- /algorithms/maximum_sum_subarray.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Maximum Sum O(n^4) 3 | Logic: 4 | --------- 5 | 1. Array[i, j] no longer contains its own value, but the sum of all within sub-rectangle (0, 0) and (i, j). this is done while taking input in O(n^2) 6 | 2. Then we can calculate the sum of any sub-rectangle (i, j) to (k, l) in O(1) 7 | 3. For (1, 2) & (3, 3), the sum is = Array[3, 3] - Array[0, 3] - Array[3, 1] + Array[0, 1] 8 | 4. To calculate the maximum sum, we need to calculate all the sum from (0, 0) to (n, n) and filter the maximum one. 9 | **/ 10 | #define MAX 1000 11 | int maxSum() { 12 | int row, col; 13 | int M[MAX + 10][MAX + 10]; 14 | scanf("%d %d", &row, &col); 15 | 16 | for(int i = 0; i < row; i++) { 17 | for(int j = 0; j < col; j++) { 18 | scanf("%d", &M[i][j]); 19 | if(i > 0) M[i][j] += M[i - 1][j]; 20 | if(j > 0) M[i][j] += M[i][j - 1]; 21 | // M[i -1][j - 1] is included both in M[i][j - 1] & M[i - 1][j]. So we need to exclude one. 22 | if(i > 0 && j > 0) M[i][j] -= M[i - 1][j - 1]; // inclusion-exclusion principle 23 | } 24 | } 25 | 26 | int maxSum = INT_MIN, sum; 27 | for(int i = 0; i < row; i++) for(int j = 0; j < col; j++) // starting cordinate 28 | for(int k = i; k < row; k++) for(int l = j; l < col; l++) { // ending cordinate 29 | sum = M[k][l]; 30 | if(i > 0) sum -= M[i - 1][l]; 31 | if(j > 0) sum -= M[k][j - 1]; 32 | if(i > 0 && j > 0) sum += M[i - 1][j - 1]; // inclusion-exclusion principle 33 | maxSum = max(maxSum, sum); 34 | } 35 | return maxSum; 36 | } 37 | 38 | /* O(n^3) */ 39 | long maxSum2() { 40 | int row, col; 41 | int M[MAX + 10][MAX + 10]; 42 | scanf("%d %d", &row, &col); 43 | 44 | //contains sum of all values of column 1 up to row n 45 | for(int i = 1; i <= row; i++) for(int j = 1; j <= col; j++) { 46 | scanf("%d", &M[i][j]); 47 | M[i][j] += M[i - 1][j]; // cumultive sum of columns [1 2 3 4 5] => [1 3 6 10 15] 48 | } 49 | 50 | long ans = M[1][1]; 51 | 52 | for(int i = 1; i <= row; i++) { 53 | for(int j = i + 1; j <= row; j++) { 54 | long tmp = 0; 55 | for(int k = 1; k <= col; k++) { 56 | tmp += (M[j][k] - M[i][k]); 57 | ans = max(ans, tmp); 58 | if(tmp < 0) tmp = 0; 59 | } 60 | } 61 | } 62 | return ans; 63 | } -------------------------------------------------------------------------------- /algorithms/mcm.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/ 4 | 5 | Time Complexity: O(n^3) 6 | Auxiliary Space: O(n^2) 7 | **/ 8 | // Matrix Ai has dimension p[i-1] x p[i] for i = 1..n 9 | int MatrixChainOrder(vector& p) { 10 | 11 | /* For simplicity of the program, one extra row and one extra column are 12 | allocated in m[][]. 0th row and 0th column of m[][] are not used */ 13 | int n = (int)p.size(); 14 | vector> dp(n, vector(n)); 15 | 16 | /* m[i,j] = Minimum number of scalar multiplications needed to compute 17 | the matrix A[i]A[i+1]...A[j] = A[i..j] where dimention of A[i] is 18 | p[i-1] x p[i] */ 19 | 20 | // cost is zero when multiplying one matrix. 21 | for (int i = 1; i < n; i++) { 22 | dp[i][i] = 0; 23 | } 24 | 25 | // L is chain length. 26 | for (int len = 2; len < n; len++) { 27 | for (int i = 1; i <= n - len + 1; i++) { 28 | int j = i + len - 1; 29 | dp[i][j] = INT_MAX; 30 | for (int k = i; k <= j - 1; k++) { 31 | int cost = dp[i][k] + dp[k + 1][j] + p[i - 1] * p[k] * p[j]; 32 | dp[i][j] = min(dp[i][j], cost); 33 | } 34 | } 35 | } 36 | 37 | return dp[1][n - 1]; 38 | } -------------------------------------------------------------------------------- /algorithms/min_cost_path.cpp: -------------------------------------------------------------------------------- 1 | /* Given a cost matrix cost[][] and a position (m, n) in cost[][], 2 | write a function that returns cost of minimum cost path to reach (m, n) from (0, 0) */ 3 | // allowed path in down or right 4 | int minCost(vector>& cost, int m, int n) { 5 | int R = (int)cost.size(); 6 | int C = (int)cost[0].size(); 7 | // Instead of following line, we can use int cache[m+1][n+1] or 8 | // dynamically allocate memoery to save space. The following line is 9 | // used to keep te program simple and make it working on all compilers. 10 | vector> dp(m + 1, vector(n + 1)); 11 | 12 | dp[0][0] = cost[0][0]; 13 | 14 | /* Initialize first column of total cost(dp) array */ 15 | for (int i = 1; i <= m; i++) { 16 | dp[i][0] = dp[i - 1][0] + cost[i][0]; 17 | } 18 | 19 | /* Initialize first row of cache array */ 20 | for (int j = 1; j <= n; j++) { 21 | dp[0][j] = dp[0][j - 1] + cost[0][j]; 22 | } 23 | 24 | /* Construct rest of the cache array */ 25 | for (int i = 1; i <= m; i++) { 26 | for(int j = 1; j <= n; j++) { 27 | dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + cost[i][j]; 28 | } 29 | } 30 | 31 | return dp[m][n]; 32 | } 33 | -------------------------------------------------------------------------------- /algorithms/min_vertex_cover.cpp: -------------------------------------------------------------------------------- 1 | #define MAX 100001 2 | 3 | int dp[MAX << 2][2]; 4 | int parent[MAX]; 5 | vector adj[MAX]; 6 | 7 | int minVertexCover(int node, bool hasGuard) { 8 | 9 | if( (int)adj[node].size() == 0 ) return 0; 10 | if( dp[node][hasGuard] != -1 ) return dp[node][hasGuard]; 11 | 12 | int sum = 0; 13 | for(int i = 0; i < (int)adj[node].size(); i++) { 14 | int v = adj[node][i]; 15 | if( v != parent[node] ) { 16 | parent[v] = node; 17 | if(!hasGuard) { 18 | sum += minVertexCover(v, true); 19 | } else { 20 | sum += min( minVertexCover(v, false), minVertexCover(v, true) ); 21 | } 22 | } 23 | } 24 | return dp[node][hasGuard] = sum + hasGuard; 25 | } 26 | 27 | /* 28 | usage: 29 | result = min( minVertexCover(1, false), minVertexCover(1, true) ); 30 | if(n > 1) printf("%d\n", result); 31 | else printf("1\n"); 32 | */ -------------------------------------------------------------------------------- /algorithms/ncr.cpp: -------------------------------------------------------------------------------- 1 | int dp[MAX][MAX]; // dp[i][j] is number of ways j items can be choosen from i items 2 | 3 | void ncr() { 4 | dp[0][0] = 1; 5 | for(int i = 1; i < MAX; ++i) { 6 | for(int j = 0; j <= i; ++j) { 7 | if(j == i or j == 0) { 8 | dp[i][j] = 1; 9 | } else { 10 | dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod; 11 | } 12 | } 13 | } 14 | } 15 | 16 | // Using combinatorics 17 | #define MAX 100001 18 | #define MOD 1000000007 19 | int fact[MAX]; 20 | int ifact[MAX]; 21 | 22 | int power(int base, int exp, int mod) { 23 | if(exp == 0) return 1; 24 | int ret = power(base, exp / 2, mod) % mod; 25 | ret = 1LL * ret * ret % mod; 26 | if(exp & 1) { 27 | ret = 1LL * ret * base % mod; 28 | } 29 | return ret; 30 | } 31 | 32 | // Modular mutiplicative inverse 33 | int modInv(int base, int mod = 1000000007) { 34 | return power(base, mod - 2, mod); 35 | } 36 | 37 | void init() { 38 | fact[0] = 1; 39 | ifact[0] = modInv(fact[0]); 40 | FOR(i, 1, MAX - 1) { 41 | fact[i] = 1LL * i * fact[i - 1] % MOD; 42 | ifact[i] = modInv(fact[i]); 43 | } 44 | } 45 | 46 | int ncr(int n, int r) { 47 | if(r > n) return 0; 48 | int ans = fact[n]; 49 | ans = 1LL * ans * ifact[r] % MOD; 50 | ans = 1LL * ans * ifact[n - r] % MOD; 51 | return ans; 52 | } -------------------------------------------------------------------------------- /algorithms/nim.cpp: -------------------------------------------------------------------------------- 1 | // first player wins if XOR > 0 2 | // second player wins otherwise 3 | // return true if first player wins 4 | bool nim(vector& piles) { 5 | int Xor = 0; 6 | int n = piles.size(); 7 | for(int i = 0; i < n; i++) { 8 | Xor ^= piles[i]; 9 | } 10 | return (Xor > 0); 11 | } 12 | 13 | // Nim variant #1 14 | // Misère Nim 15 | // Classical nim except the player who removes the last stone will loose 16 | bool misereNim(vector& piles) { 17 | int Xor = 0; 18 | int n = (int)piles.size(); 19 | bool allOnes = true; 20 | for(int i = 0; i < n; i++) { 21 | if(piles[i] != -1) { 22 | allOnes = false; 23 | break; 24 | } 25 | Xor ^= piles[i]; 26 | } 27 | if(allOnes) { 28 | return false; 29 | } 30 | return (Xor > 0); 31 | } 32 | 33 | // Nim variant #2 34 | // Nimble game 35 | /*** 36 | Two people are playing Nimble! The rules of the game are: 37 | 38 | The game is played on a line of n squares, indexed from 0 to n - 1. Each square i (where i < n) contains ci coins 39 | nimble.png 40 | The players move in alternating turns. During each move, the current player must remove exactly 1 coin from square i and move it to square j 41 | if and only if j < i. 42 | The game ends when all coins are in square 0 and nobody can make a move. The first player to have no available move loses the game. 43 | ***/ 44 | bool nimble(vector& squares) { 45 | int n = (int)squares.size(); 46 | int Xor = 0; 47 | for(int i = 0; i < n; i++) { 48 | // optimization: xoring i with Xor 'squares[i]' times 49 | if(squares[i] & 1) { 50 | Xor ^= i; 51 | } 52 | } 53 | return (Xor > 0); 54 | } 55 | 56 | // Nim variant #3 57 | // Poker nim 58 | // Bogus nim: Exactly nim except now 59 | // any player can add one or more stones to any piles 60 | bool pokerNim(vector& piles) { 61 | // adding stones has no effect as in the next turn, the other player can mimic the first player turn 62 | // and remove same number of stones 63 | return nim(piles); 64 | } 65 | 66 | // NIm variant #4 67 | // Prime power game 68 | // Given a number, any player can divide the number of with power of prime 69 | // whoever has no turn left and found the number 1, will loose 70 | // n = 56700 = 2^2 × 3^4 × 5^2 × 7^1 turn out as nim game with {2, 4, 2, 1} piles 71 | // similiar problem: https://www.hackerrank.com/contests/5-days-of-game-theory/challenges/tower-breakers-2 72 | bool primePower(int n) { 73 | vectorfactors; 74 | primeFactors(n, factors); 75 | return nim(factors); 76 | } -------------------------------------------------------------------------------- /algorithms/nqueen.cpp: -------------------------------------------------------------------------------- 1 | int x[9]; 2 | 3 | bool isPlacable(int queen, int row) { 4 | for(int prev = 1; prev < queen; prev++) { 5 | if (x[prev] == row || abs(x[prev] - row) == abs(prev - queen) ) { 6 | return false; 7 | } 8 | } 9 | return true; 10 | } 11 | 12 | // nQueen(1); 13 | void nQueen(int queen) { 14 | for(int row = 1; row <= 8; row++) { 15 | if (isPlacable(queen, row)) { 16 | x[queen] = row; 17 | // found a solution 18 | if (queen == 8) { 19 | for(int i = 1; i <= 8; i++) { 20 | // print 21 | } 22 | return; 23 | } 24 | nQueen(queen + 1); 25 | } 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /algorithms/optimal_search_tree.cpp: -------------------------------------------------------------------------------- 1 | #define MAX 1000 2 | int sum[MAX]; 3 | 4 | /* A Dynamic Programming based function that calculates minimum cost of 5 | a Binary Search Tree. */ 6 | int optimalSearchTree(int keys[], int freq[], int n) { 7 | /* Create an auxiliary 2D matrix to store results of subproblems */ 8 | int cost[n][n]; 9 | 10 | /* cost[i][j] = Optimal cost of binary search tree that can be 11 | formed from keys[i] to keys[j]. 12 | cost[0][n-1] will store the resultant cost */ 13 | 14 | // For a single key, cost is equal to frequency of the key 15 | for (int i = 0; i < n; i++) 16 | cost[i][i] = freq[i]; 17 | 18 | // Now we need to consider chains of length 2, 3, ... . 19 | // L is chain length. 20 | for (int L = 2; L <= n; L++) { 21 | // i is row number in cost[][] 22 | for (int i = 0; i <= n - L + 1; i++) { 23 | // Get column number j from row number i and chain length L 24 | int j = i + L - 1; 25 | cost[i][j] = INT_MAX; 26 | 27 | // Try making all keys in interval keys[i..j] as root 28 | for (int r = i; r <= j; r++) { 29 | // c = cost when keys[r] becomes root of this subtree 30 | int c = ((r > i) ? cost[i][r - 1] : 0) + 31 | ((r < j) ? cost[r + 1][j] : 0) + 32 | sum[j] - sum[i - 1]; 33 | if (c < cost[i][j]) { 34 | cost[i][j] = c; 35 | //printf("%d %d %d\n", i, j, keys[r]); 36 | } 37 | } 38 | } 39 | } 40 | #if 0 41 | // print the cost matrix 42 | for (int i = 0; i < n; i++) { 43 | for (int j = 0; j < n; j++) { 44 | if(i <= j) printf("%6d", cost[i][j]); 45 | else printf(" "); 46 | } 47 | printf("\n"); 48 | } 49 | #endif 50 | return cost[0][n - 1]; 51 | } 52 | 53 | // Driver program to test above functions 54 | int main() { 55 | int keys[] = {10, 12, 20}; 56 | int freq[] = {34, 8, 50}; 57 | int n = sizeof(keys)/sizeof(keys[0]); 58 | 59 | // precalculating sum 60 | for (int i = 0; i < n; i++) { 61 | sum[i] = sum[i - 1] + freq[i]; 62 | } 63 | 64 | printf("Cost: %d\n", optimalSearchTree(keys, freq, n)); 65 | return 0; 66 | } -------------------------------------------------------------------------------- /algorithms/permutation_generator.cpp: -------------------------------------------------------------------------------- 1 | char arr[] = {'a','b','c','d'}; 2 | int N = sizeof(arr) / sizeof(arr[0]); 3 | vector result; 4 | int mask = 0, maxN = (1 << N) - 1; 5 | 6 | bool Check(int N, int pos) { 7 | return (bool)(N & (1 << pos)); 8 | } 9 | 10 | int Set(int N, int pos) { 11 | return N | (1 << pos); 12 | } 13 | 14 | int Reset(int N, int pos) { 15 | return N & ~(1 << pos); 16 | } 17 | 18 | void bktk_bitmask() { 19 | if(mask == maxN) { 20 | for(int i = 0; i < N; i++) 21 | printf("%c", result[i]); 22 | putchar('\n'); 23 | return; 24 | } 25 | for(int i = 0; i < N; i++) { 26 | if(!Check(mask, i) ) { 27 | mask = Set(mask, i); 28 | result.push_back( arr[i] ); 29 | bktk_bitmask(); 30 | mask = Reset(mask, i); 31 | result.pop_back(); 32 | } 33 | } 34 | } 35 | 36 | bool taken[20] = {false}; 37 | void bktk() { 38 | if(result.size() == N) { 39 | for(int i = 0; i < N; i++) 40 | printf("%c", result[i]); 41 | putchar('\n'); 42 | return; 43 | } 44 | for(int i = 0; i < N; i++) { 45 | if(taken[i] == false) { 46 | taken[i] = true; 47 | result.push_back( arr[i] ); 48 | bktk(); 49 | taken[i] = false; 50 | result.pop_back(); 51 | } 52 | } 53 | } 54 | 55 | void permute() { 56 | do{ 57 | } while(prev_permutation(arr, arr + N)); 58 | do{ 59 | // print permutation 60 | } while(next_permutation(arr, arr + N)); 61 | } 62 | 63 | void permuteUtil(int indx) { 64 | if(indx == N) { 65 | for(int i = 0; i < N; i++) { 66 | printf("%c ", arr[i]); 67 | } 68 | printf("\n"); 69 | return; 70 | } 71 | for(int i = indx; i < N; i++) { 72 | swap(arr[indx], arr[i]); 73 | permuteUtil(indx + 1); 74 | swap(arr[indx], arr[i]); 75 | } 76 | } 77 | 78 | void permute2() { 79 | return permuteUtil(0); 80 | } -------------------------------------------------------------------------------- /algorithms/phi.cpp: -------------------------------------------------------------------------------- 1 | // To find positive integers below n that are relatively prime 2 | // i.e. 36 = 2^3 * 3^2, Phi(36) = 36 * (1 - 1/2)* (1 - 1/3) = 12 3 | int phi (int n) { 4 | if ( n == 1 ) 5 | return 0; 6 | int output = n; 7 | 8 | if ( n % 2 == 0 ) { 9 | output -= (output / 2); 10 | while ( n % 2 == 0 ) 11 | n /= 2; 12 | } 13 | 14 | for ( int i = 3; i * i <= n; i += 2 ) { // i <= sqrtN may be ?? 15 | if ( n % i == 0 ) { 16 | output -= (output / i); 17 | while ( n % i == 0 ) 18 | n /= i; 19 | } 20 | } 21 | 22 | if ( n > 1 ) 23 | output -= (output / n); 24 | 25 | return output; 26 | } 27 | 28 | // using prime sieve 29 | // generate prime numbers upto certain limit using sieve/segmented sieve 30 | // sieve(sqrt(n)); 31 | int phi (int n) { 32 | int phi = n; 33 | int sqrtN = sqrt(n); 34 | for(int i = 0; i < (int)primes.size() and primes[i] <= sqrtN; i++) { 35 | if(n % primes[i] == 0) { 36 | phi *= (1 - 1 / (double) primes[i]); 37 | while(n % primes[i] == 0) { 38 | n /= primes[i]; 39 | } 40 | } 41 | } 42 | 43 | if(n > 1) { 44 | phi *= (1 - 1 / (double) n); 45 | } 46 | 47 | return phi; 48 | } -------------------------------------------------------------------------------- /algorithms/primality_test.cpp: -------------------------------------------------------------------------------- 1 | // optimized school method O(sqrt(n)) 2 | // observation: all primes are of the form 6k ± 1, with the exception of 2 and 3 3 | bool isPrime(int n) { 4 | if(n <= 1) return false; 5 | if(n <= 3) return true; 6 | if(n % 2 == 0 or n % 3 == 0) { 7 | return false; 8 | } 9 | int sqrtN = sqrt(n); 10 | for(int i = 5; i <= sqrtN; i += 6) { 11 | if(n % i == 0 or n % (i + 2) == 0) { 12 | return false; 13 | } 14 | } 15 | 16 | return true; 17 | } 18 | 19 | 20 | 21 | // Miller-Rabin test 22 | // How it works: 23 | /*** 24 | 1. Fermat’s theorem states that, If n is a prime number, then for every a, 1 <= a < n, a^(n-1) % n = 1 25 | 2. Base cases make sure that n must be odd. Since n is odd, n-1 must be even. 26 | And an even number can be written as d * 2s where d is an odd number and s > 0. 27 | From above two points, for every randomly picked number in range [2, n-2], value of a^(d*2r) % n must be 1. 28 | 3. As per Euclid’s Lemma, if x2 % n = 1 or (x2 – 1) % n = 0 or (x-1)(x+1)% n = 0, 29 | then, for n to be prime, either n divides (x-1) or n divides (x+1). Which means either x % n = 1 or x % n = -1. 30 | 4. From points 2 and 3, we can conclude 31 | For n to be prime, either 32 | a^d % n = 1 33 | OR 34 | a^(d*2i) % n = -1 35 | for some i, where 0 <= i <= r-1. 36 | ***/ 37 | #define i64 unsigned long long 38 | 39 | // c <= a x b 40 | i64 mulmod(i64 a, i64 b, i64 mod) { 41 | i64 x = 0, y = a % mod; 42 | while(b) { 43 | if(b & 1) { 44 | x = (x + y) % mod; 45 | } 46 | y = (y << 1) % mod; 47 | b >>= 1; 48 | } 49 | return x; 50 | } 51 | 52 | // modular exponentiation for numbers where base * base can exceed LLONG_MAX 53 | i64 power(i64 base, i64 exp, i64 mod) { 54 | i64 x = 1, y = base % mod; 55 | while(exp) { 56 | if(exp & 1) { 57 | x = mulmod(x, y, mod); 58 | } 59 | y = mulmod(y, y, mod); 60 | exp >>= 1; 61 | } 62 | return x; 63 | } 64 | 65 | // returns false if n is composite and returns true if n is probably prime. 66 | // d is an odd number such that d*2^r = n - 1 for some r >= 1 67 | bool millerTest(i64 n, i64 d) { 68 | 69 | // pick a random number between [1 ... n - 1] 70 | i64 a = rand() % (n - 1) + 1; 71 | 72 | // compute a^d % n 73 | i64 x = power(a, d, n); 74 | 75 | 76 | // Keep squaring x while one of the following doesn't 77 | // happen 78 | // (i) d does not reach n - 1 79 | // (ii) (x^2) % n is not 1 80 | // (iii) (x^2) % n is not n - 1 81 | while(d != n - 1 and x != 1 and x != n - 1) { 82 | x = mulmod(x, x, n); 83 | d <<= 1; 84 | } 85 | 86 | if(x != n - 1 and !(d & 1)) { 87 | // composite number 88 | return false; 89 | } 90 | 91 | return true; 92 | } 93 | 94 | // returns false if n is composite and returns true if n is probably prime. 95 | // iter is an input parameter that determines accuracy level. Higher value of iter indicates more accuracy. 96 | // accurate till 10^18 e.g. isPrime(LLONG_MAX) works even only in 1 iterations 97 | bool isPrime(i64 n, int iter = 1) { 98 | 99 | // corner cases 100 | if(n < 2) { 101 | return false; 102 | } 103 | if(n == 2) { 104 | return true; 105 | } 106 | if(!(n & 1)) { // even 107 | return false; 108 | } 109 | 110 | // Find d such that n = d * 2^r + 1 for some r >= 1 111 | i64 d = n - 1; 112 | while(!(d & 1)) { 113 | d >>= 1; 114 | } 115 | 116 | // check iter times 117 | for(int i = 0; i < iter; i++) { 118 | if(!millerTest(n, d)) { 119 | return false; 120 | } 121 | } 122 | return true; 123 | } -------------------------------------------------------------------------------- /algorithms/prime.cpp: -------------------------------------------------------------------------------- 1 | vector primes; 2 | vector marked; 3 | 4 | void sieve(int n) { 5 | marked = vector(n + 1, false); 6 | int sqrtN = sqrt(n); 7 | for(int i = 3; i <= sqrtN; i += 2) { 8 | if(!marked[i]) { 9 | for(int j = i; j <= n; j += (i << 1)) { 10 | marked[j] = true; 11 | } 12 | marked[i] = false; 13 | } 14 | } 15 | if(n >= 2) primes.push_back(2); 16 | for(int i = 3; i <= n; i += 2) { 17 | if(!marked[i]) { 18 | primes.push_back(i); 19 | } 20 | } 21 | } 22 | 23 | /*** 24 | calculate primes between L and R where 1 <= L <= R <= INT_MAX and 0 <= R - L <= 10^5 25 | 1. generate primes using sieve upto sqrt(INT_MAX) 26 | 2. using those primes calculate segmented sieve/primes between ranges 27 | ***/ 28 | void segmentedSieve(unsigned int left, unsigned int right) { 29 | int sqrtR = sqrt(right); 30 | marked = vector(right - left + 1, false); // marked.resize(right - left + 1, false) don't work :( 31 | 32 | for(int i = 1; i < primes.size() and primes[i] <= sqrtR; i++) { 33 | // offset is equal or immediate larger prime of left 34 | int offset = ((left + primes[i] - 1) / primes[i]) * primes[i]; 35 | for(int j = offset; j <= right; j += primes[i]) { 36 | marked[j - left] = true; 37 | } 38 | if(offset == primes[i]) { 39 | marked[offset - left] = false; 40 | } 41 | 42 | } 43 | 44 | if(left <= 2 and 2 <= right) { 45 | // prime => 2 46 | } 47 | for(int i = max(((left & 1) ? left : left + 1), 3u); i <= right; i += 2) { 48 | if(!marked[i - left]) { 49 | // prime => i 50 | } 51 | } 52 | } 53 | 54 | // prime factorization using sieve 55 | // 45 = 3^2 * 5^1 56 | void primeFactor(int x, vector>& factors) { 57 | for(int i = 0; i < primes.size() and primes[i] <= x; i++) { 58 | if(x % primes[i] == 0) { 59 | int p = primes[i]; 60 | int freq = 0; 61 | while(x % p == 0) { 62 | freq++; 63 | x /= p; 64 | } 65 | factors.push_back({p, freq}); 66 | } 67 | } 68 | } 69 | 70 | // quick factorization without any preprocess 71 | void primeFactor2(int x, vector>& factors) { 72 | int sqrtX = sqrt(x); 73 | if(x % 2 == 0) { 74 | int p = 2; 75 | int freq = 0; 76 | while(x % p == 0) { 77 | x /= p; 78 | freq++; 79 | } 80 | factors.push_back({p, freq}); 81 | } 82 | for(int i = 3; i <= sqrtX; i += 2) { 83 | if(x % i == 0) { 84 | int p = i; 85 | int freq = 0; 86 | while(x % p == 0) { 87 | freq++; 88 | x /= p; 89 | } 90 | factors.push_back({p, freq}); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /algorithms/prime_ring.cpp: -------------------------------------------------------------------------------- 1 | // prime ring where the sum of numbers in two adjacent circles should be a prime 2 | int n; 3 | int a [20]; 4 | bool available [20]; 5 | int isPrime [42] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 6 | 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 7 | 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 8 | 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 9 | 1 10 | }; 11 | 12 | bool valid (int indx, int ring) { 13 | if ( ring == n - 1 ) { 14 | if (isPrime [a [ring - 1] + indx] && isPrime [indx + 1]) 15 | return true; 16 | return false; 17 | } 18 | return isPrime [a [ring - 1] + indx]; 19 | } 20 | 21 | // bktk(1); 22 | void bktk (int ring) { 23 | if ( ring == n ) { 24 | printf ("%d", a [0]); 25 | for ( int i = 1; i < n; i++ ) 26 | printf (" %d", a [i]); 27 | printf ("\n"); 28 | return; 29 | } 30 | 31 | for ( int i = 2; i <= n; i++ ) { 32 | if ( available [i] ) { 33 | if ( valid (i, ring) ) { 34 | available [i] = false; 35 | a [ring] = i; 36 | bktk (ring + 1); 37 | available [i] = true; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /algorithms/queue.cpp: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | #include 5 | #include 6 | 7 | template 8 | class queue { 9 | public: 10 | ~queue(); 11 | bool empty() const; 12 | size_t size() const; 13 | T const& front() const; 14 | T& front(); 15 | void push(T const& data); 16 | void push(T&& data); 17 | //void emplace (T&&... args); 18 | // void swap (queue& x); 19 | void pop(); 20 | 21 | private: 22 | size_t elements = 0; 23 | struct node { 24 | T data; 25 | node *next; 26 | 27 | node(T const& data, node* next) 28 | : data(data) 29 | , next(next) { 30 | } 31 | 32 | node(T&& data, node* next) 33 | : data(std::move(data)) 34 | , next(next) { 35 | } 36 | }; 37 | node *head = nullptr; 38 | node *tail = nullptr; 39 | }; 40 | 41 | template 42 | queue::~queue() { 43 | node *curr; 44 | while(head) { 45 | curr = head; 46 | head = head->next; 47 | delete curr; 48 | } 49 | } 50 | 51 | template 52 | bool queue::empty() const { 53 | return elements == 0; 54 | // return head == nullptr; 55 | } 56 | 57 | template 58 | size_t queue::size() const { 59 | return elements; 60 | } 61 | 62 | template 63 | T const& queue::front() const { 64 | if(head == nullptr) 65 | throw std::runtime_error("Invalid Action"); 66 | return head->data; 67 | } 68 | 69 | template 70 | T& queue::front() { 71 | if(head == nullptr) 72 | throw std::runtime_error("Invalid Action"); 73 | return head->data; 74 | } 75 | 76 | template 77 | void queue::push(T const& data) { 78 | node *newNode = new node(data, nullptr); 79 | if(head == nullptr) head = newNode; 80 | else tail->next = newNode; 81 | tail = newNode; 82 | ++elements; 83 | } 84 | template 85 | void queue::push(T&& data) { 86 | node *newNode = new node(std::move(data), nullptr); 87 | if(head == nullptr) head = newNode; 88 | else tail->next = newNode; 89 | tail = newNode; 90 | ++elements; 91 | } 92 | 93 | template 94 | void queue::pop() { 95 | if(head == nullptr) 96 | throw std::runtime_error("Invalid Action"); 97 | 98 | node* remove = head; 99 | head = head->next; 100 | delete remove; 101 | 102 | --elements; 103 | } 104 | 105 | #endif // QUEUE_H -------------------------------------------------------------------------------- /algorithms/rabin_karp.cpp: -------------------------------------------------------------------------------- 1 | // average time: O(n + m), worst case: O(n * m) 2 | // popular application: plagarism check 3 | 4 | // d is the number of characters in input alphabet 5 | #define d 256 6 | 7 | void rkSearch(string const& pattern, string const& text) { 8 | int m = (int)pattern.length(); 9 | int n = (int)text.length(); 10 | 11 | int q = 101; // some small prime, must be less than INT_MAX 12 | 13 | int h = 1; 14 | // h = pow(d, M - 1) % q 15 | for(int i = 0; i < m - 1; i++) { 16 | h = (h * d) % q; 17 | } 18 | 19 | // calculate the hash value of pattern and first window of text 20 | int pHash = 0; 21 | int tHash = 0; 22 | for(int i = 0; i < m; i++) { 23 | pHash = (d * pHash + pattern[i]) % q; 24 | tHash = (d * tHash + text[i]) % q; 25 | } 26 | 27 | // slide the pattern over text one by one 28 | for(int i = 0; i <= n - m; i++) { 29 | 30 | // check the hash value of current window of text and pattern 31 | // If the hash values match then only check for characters one by one 32 | if(pHash == tHash) { 33 | int j; 34 | for(j = 0; j < m; j++) { 35 | if(text[i + j] != pattern[j]) { 36 | break; 37 | } 38 | } 39 | if(j == m) { 40 | // pattern found at index position i 41 | } 42 | } 43 | 44 | // calculate hash value of next window of text 45 | // remove leading digit, add trailing digit 46 | if(i < n - m) { 47 | tHash = (d * (tHash - text[i] * h) + text[i + m]) % q; 48 | 49 | // incase of getting negative value of tHash after modulo operation 50 | if(tHash < 0) { 51 | tHash += q; 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /algorithms/scc.cpp: -------------------------------------------------------------------------------- 1 | // How does this work? See http://www.geeksforgeeks.org/strongly-connected-components/ 2 | 3 | #define Max 105 4 | vector adj[Max], adj2[Max]; 5 | bool visited[Max]; 6 | int N; 7 | 8 | stack Stack; 9 | 10 | void dfs1(int u) { 11 | visited[u] = true; 12 | for(int i = 0, n = (int)adj[u].size(); i < n; ++i) { 13 | int v = adj[u][i]; 14 | if(!visited[v]) 15 | dfs1(v); 16 | } 17 | Stack.push(u); 18 | } 19 | 20 | void transposeGraph() { 21 | for(int u = 0; u < N; ++u) { 22 | for(int i = 0, n = (int)adj[u].size(); i < n; ++i) { 23 | int v = adj[u][i]; 24 | adj2[v].pb(u); 25 | } 26 | } 27 | } 28 | 29 | void dfs2(int u) { 30 | visited[u] = true; 31 | // printf("%d ", u); 32 | for(int i = 0, n = (int)adj2[u].size(); i < n; ++i) { 33 | int v = adj2[u][i]; 34 | if(!visited[v]) 35 | dfs2(v); 36 | } 37 | } 38 | 39 | void kosarajuSCC() { 40 | memset(visited, false, sizeof visited); 41 | for(int i = 0; i < N; ++i) if(!visited[i]) dfs1(i); 42 | transposeGraph(); 43 | memset(visited, false, sizeof visited); 44 | while(!Stack.empty()) { 45 | int v = Stack.top(); 46 | Stack.pop(); 47 | if(!visited[v]) { 48 | dfs2(v); 49 | // printf("\n"); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /algorithms/segment_tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * generalized for Range maximum/minimum/sum query 3 | * Operation #1: Build Segment Tree upon an given array 4 | * Operation #2: Update the element of given index with value val 5 | * Operation #3: Query max/min/sum element within range [i, j] 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | // code for three types of operation 14 | enum RequestCode {rangeSum, rangeMin, rangeMax}; 15 | 16 | vector segment_tree; // will contain the node value of ST 17 | 18 | // array of data upon which we will build segment tree 19 | int data[] = {21, 2, 7, 3, 4, 5, 1, 6, 9, 32, 11, 13, 23, 17, 8}; 20 | size_t arrLength = sizeof data / sizeof(data[0]); // size of the array 21 | 22 | /** 23 | * allocate & initialize segment tree 24 | */ 25 | void initSegmentTree() { 26 | // the required segment tree array length is 2*2^(floor(log2(N))) + 1; 27 | int length = 2 * pow(2.0, floor(log((double) arrLength ) / log(2.0)) + 1 ); 28 | segment_tree.clear(); 29 | segment_tree.resize(length, 0); 30 | } 31 | 32 | /** 33 | * Time: O(n*log(n)) 34 | * functions for building segment tree 35 | * buildHelper(code, node, begin, end) 36 | * buildSegmentTree(code) 37 | */ 38 | void buildHelper( RequestCode code, int node, int begin, int end ) { 39 | if (begin == end) { 40 | if (code == rangeSum) segment_tree[node] = data[begin]; 41 | else segment_tree[node] = begin; 42 | return; 43 | } 44 | int leftIndx = node << 1, rightIndx = leftIndx | 1; 45 | 46 | buildHelper(code, leftIndx, begin, (begin + end) / 2); 47 | buildHelper(code, rightIndx, (begin + end) / 2 + 1, end); 48 | 49 | int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx]; 50 | 51 | if(code == rangeSum) segment_tree[node] = lContent + rContent; 52 | if(code == rangeMin) segment_tree[node] = ( data[lContent] <= data[rContent] ) ? lContent : rContent; 53 | if(code == rangeMax) segment_tree[node] = ( data[lContent] >= data[rContent] ) ? lContent : rContent; 54 | 55 | } 56 | 57 | void buildSegmentTree(RequestCode code) { 58 | buildHelper(code, 1, 0, arrLength - 1); 59 | } 60 | 61 | /** 62 | * Time: O(log(n)) 63 | * query functions for ST 64 | * queryHelper(code, node, begin, end, lowerRange, upperRange) 65 | * query(code, loweRange, upperRange) 66 | */ 67 | //divide & conquer fashion [r1,r2] = [r1, (r1+r2)/2] , [(r1+r2)/2 + 1, r2] 68 | int queryHelper(RequestCode code, int node, int begin, int end, int i, int j) { 69 | // if the current interval does not intersect query interval 70 | if (i > end || j < begin) return -1; 71 | 72 | if (begin >= i && end <= j) return segment_tree[node]; 73 | 74 | // compute the minimum position in the left and right part of the interval 75 | int leftIndx = node << 1, rightIndx = leftIndx | 1; 76 | int pos1 = queryHelper(code, leftIndx, begin, (begin + end) / 2, i, j); 77 | int pos2 = queryHelper(code, rightIndx, (begin + end) / 2 + 1, end, i, j); 78 | 79 | // return the position where the overall minimum is 80 | if(pos1 == -1) return pos2; // can happen if we try to access segment outside query 81 | if(pos2 == -1) return pos1; 82 | 83 | if (code == rangeSum) { 84 | return pos1 + pos2; 85 | } else if(code == rangeMin) { 86 | return (data[pos1] <= data[pos2]) ? pos1 : pos2; 87 | } else return (data[pos1] >= data[pos2]) ? pos1 : pos2; 88 | } 89 | 90 | int query(RequestCode code, int lower, int upper) { 91 | return queryHelper(code, 1, 0, arrLength - 1, lower, upper); 92 | } 93 | 94 | /** 95 | * Time: O(log(n)) 96 | * update functions for segment tree 97 | * updates an index with given value 98 | * updateHelper(code, begin, end, index, value) 99 | * update(code, index, value) 100 | */ 101 | /* root to leaf */ 102 | void updateHelper(RequestCode code, int node, int begin, int end, int index, int value ) { 103 | 104 | // this is the only condition and change that makes this updateHelper() function different from buildHelper() 105 | if( index < begin || index > end || begin > end ) return; 106 | 107 | if( begin == end ) { 108 | data[begin] = value; // data array is needed to be updated 109 | 110 | // rest of the code is same as buildHelper() method 111 | if(code == rangeSum) segment_tree[node] = data[begin]; 112 | else segment_tree[node] = begin; 113 | return; 114 | } 115 | int leftIndx = node << 1, rightIndx = leftIndx | 1; 116 | 117 | updateHelper(code, leftIndx, begin, ( begin + end ) >> 1, index, value ); 118 | updateHelper(code, rightIndx, ( ( begin + end ) >> 1 ) + 1, end, index, value ); 119 | 120 | int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx]; 121 | 122 | if(code == rangeSum) segment_tree[node] = lContent + rContent; 123 | else if(code == rangeMin) segment_tree[node] = ( data[lContent] <= data[rContent] ) ? lContent : rContent; 124 | else if(code == rangeMax) segment_tree[node] = ( data[lContent] >= data[rContent] ) ? lContent : rContent; 125 | } 126 | 127 | void update(RequestCode code, int index, int item) { 128 | updateHelper(code, 1, 0, arrLength - 1, index, item); 129 | } 130 | 131 | int main() { 132 | initSegmentTree(); 133 | 134 | buildSegmentTree(rangeMin); 135 | // query command for Range Minimum query from 0 to 8 136 | cout << query(rangeMin, 0, 8) << "\n"; 137 | 138 | // update index 6 with value 100 139 | update(rangeMin, 6, 100); 140 | cout << query(rangeMin, 0, 8) << "\n"; 141 | 142 | buildSegmentTree(rangeMax); 143 | cout << query(rangeMax, 0, 8) << "\n"; 144 | 145 | buildSegmentTree(rangeSum); 146 | cout << query(rangeSum, 0, 8); 147 | return 0; 148 | } -------------------------------------------------------------------------------- /algorithms/segment_tree_lazy.cpp: -------------------------------------------------------------------------------- 1 | // Increase each value by x from segment s1 to s2 2 | vector segment_tree; 3 | vector propagation; // for lazy propagation 4 | 5 | int data[] = {1, 2, 3, 4, 5, 6}; 6 | size_t arrLength = sizeof data / sizeof(data[0]); 7 | 8 | 9 | void initSegmentTree() { 10 | // the required segment tree array length is 2*2^(floor(log2(N))) + 1; 11 | int length = 2 * pow(2.0, floor(log((double) arrLength ) / log(2.0)) + 1 ); 12 | segment_tree.clear(); 13 | segment_tree.resize(length, 0); 14 | propagation.clear(); 15 | propagation.resize(length, 0); 16 | } 17 | 18 | 19 | void buildHelper(int node, int begin, int end ) { 20 | if (begin == end) { 21 | segment_tree[node] = data[begin]; 22 | return; 23 | } 24 | int leftIndx = 2 * node, rightIndx = 2 * node + 1; 25 | 26 | buildHelper(leftIndx, begin, (begin + end) / 2); 27 | buildHelper(rightIndx, (begin + end) / 2 + 1, end); 28 | 29 | int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx]; 30 | 31 | segment_tree[node] = lContent + rContent; 32 | 33 | } 34 | 35 | void buildSegmentTree() { 36 | buildHelper(1, 0, arrLength - 1); 37 | } 38 | 39 | 40 | //[r1,r2] = [r1, (r1+r2)/2] , [(r1+r2)/2 + 1, r2] 41 | int queryHelper(int node, int begin, int end, int i, int j) { 42 | // if the current interval does not intersect query interval 43 | if (i > end or j < begin) return -1; 44 | 45 | if (begin >= i and end <= j) return segment_tree[node]; 46 | 47 | // compute the minimum position in the left and right part of the interval 48 | int pos1 = queryHelper(2 * node, begin, (begin + end) / 2, i, j); 49 | int pos2 = queryHelper(2 * node + 1, (begin + end) / 2 + 1, end, i, j); 50 | 51 | // return the position where the overall minimum is 52 | if(pos1 == -1) return pos2; // can happen if we try to access segment outside query 53 | if(pos2 == -1) return pos1; 54 | 55 | return pos1 + pos2; 56 | } 57 | 58 | int query(int lower, int upper) { 59 | return queryHelper(1, 0, arrLength - 1, lower, upper); 60 | } 61 | 62 | void lazyUpdateHelper(int node, int begin, int end, int i, int j, int value ) { 63 | 64 | // this is the only condition and change that makes this updateHelper() function different from buildHelper() 65 | if (i > end or j < begin) return; 66 | 67 | // node's range is inside the range to be updated 68 | if (begin >= i and end <= j) { 69 | propagation[node] += value; 70 | segment_tree[node] += (end - begin + 1) * value; 71 | return; 72 | } 73 | 74 | int leftIndx = node * 2, rightIndx = node * 2 + 1; 75 | 76 | lazyUpdateHelper(leftIndx, begin, ( begin + end ) / 2, i, j, value ); 77 | lazyUpdateHelper(rightIndx, ( begin + end ) / 2 + 1, end, i, j, value ); 78 | 79 | int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx]; 80 | 81 | segment_tree[node] = lContent + rContent + (end - begin + 1) * propagation[node]; 82 | } 83 | 84 | void lazyUpdate(int lower, int upper, int item) { 85 | lazyUpdateHelper(1, 0, arrLength - 1, lower, upper, item); 86 | } 87 | 88 | int lazyQueryHelper(int node, int begin, int end, int i, int j, int carry = 0) { 89 | // if the current interval does not intersect query interval 90 | if (i > end or j < begin) return -1; 91 | 92 | if (begin >= i and end <= j) return segment_tree[node] + carry * (end- begin + 1); 93 | 94 | // compute the minimum position in the left and right part of the interval 95 | int pos1 = lazyQueryHelper(2 * node, begin, (begin + end) / 2, i, j, carry + propagation[node]); 96 | int pos2 = lazyQueryHelper(2 * node + 1, (begin + end) / 2 + 1, end, i, j, carry + propagation[node]); 97 | 98 | // return the position where the overall minimum is 99 | if(pos1 == -1) return pos2; // can happen if we try to access segment outside query 100 | if(pos2 == -1) return pos1; 101 | 102 | return pos1 + pos2; 103 | } 104 | 105 | int lazyQuery(int lower, int upper) { 106 | return lazyQueryHelper(1, 0, arrLength - 1, lower, upper, 0); 107 | } -------------------------------------------------------------------------------- /algorithms/splay.cpp: -------------------------------------------------------------------------------- 1 | // source: Geeksforgeeks 2 | // An AVL tree node 3 | struct node { 4 | int key; 5 | struct node *left, *right; 6 | }; 7 | 8 | /* Helper function that allocates a new node with the given key and 9 | NULL left and right pointers. */ 10 | struct node* newNode(int key) { 11 | struct node* node = (struct node*)malloc(sizeof(struct node)); 12 | node->key = key; 13 | node->left = node->right = NULL; 14 | return (node); 15 | } 16 | 17 | // A utility function to right rotate subtree rooted with y 18 | // See the diagram given above. 19 | struct node *rightRotate(struct node *x) { 20 | struct node *y = x->left; 21 | x->left = y->right; 22 | y->right = x; 23 | return y; 24 | } 25 | 26 | // A utility function to left rotate subtree rooted with x 27 | // See the diagram given above. 28 | struct node *leftRotate(struct node *x) { 29 | struct node *y = x->right; 30 | x->right = y->left; 31 | y->left = x; 32 | return y; 33 | } 34 | 35 | // This function brings the key at root if key is present in tree. 36 | // If key is not present, then it brings the last accessed item at 37 | // root. This function modifies the tree and returns the new root 38 | struct node *splay(struct node *root, int key) { 39 | // Base cases: root is NULL or key is present at root 40 | if (root == NULL or root->key == key) 41 | return root; 42 | 43 | // Key lies in left subtree 44 | if (root->key > key) { 45 | // Key is not in tree, we are done 46 | if (root->left == NULL) return root; 47 | 48 | // Zig-Zig (Left Left) 49 | if (root->left->key > key) { 50 | // First recursively bring the key as root of left-left 51 | root->left->left = splay(root->left->left, key); 52 | 53 | // Do first rotation for root, second rotation is done after else 54 | root = rightRotate(root); 55 | } else if (root->left->key < key) { // Zig-Zag (Left Right) 56 | // First recursively bring the key as root of left-right 57 | root->left->right = splay(root->left->right, key); 58 | 59 | // Do first rotation for root->left 60 | if (root->left->right != NULL) 61 | root->left = leftRotate(root->left); 62 | } 63 | 64 | // Do second rotation for root 65 | return (root->left == NULL)? root: rightRotate(root); 66 | } else { // Key lies in right subtree 67 | // Key is not in tree, we are done 68 | if (root->right == NULL) return root; 69 | 70 | // Zag-Zig (Right Left) 71 | if (root->right->key > key) { 72 | // Bring the key as root of right-left 73 | root->right->left = splay(root->right->left, key); 74 | 75 | // Do first rotation for root->right 76 | if (root->right->left != NULL) 77 | root->right = rightRotate(root->right); 78 | } else if (root->right->key < key) { // Zag-Zag (Right Right) 79 | // Bring the key as root of right-right and do first rotation 80 | root->right->right = splay(root->right->right, key); 81 | root = leftRotate(root); 82 | } 83 | 84 | // Do second rotation for root 85 | return (root->right == NULL)? root: leftRotate(root); 86 | } 87 | } 88 | 89 | // The search function for Splay tree. Note that this function 90 | // returns the new root of Splay Tree. If key is present in tree 91 | // then, it is moved to root. 92 | struct node *search(struct node *root, int key) { 93 | return splay(root, key); 94 | } 95 | 96 | // A utility function to print preorder traversal of the tree. 97 | // The function also prints height of every node 98 | void preOrder(struct node *root) { 99 | if (root != NULL) { 100 | printf("%d ", root->key); 101 | preOrder(root->left); 102 | preOrder(root->right); 103 | } 104 | } 105 | 106 | /* Driver program to test above function*/ 107 | int main() { 108 | struct node *root = newNode(100); 109 | root->left = newNode(50); 110 | root->right = newNode(200); 111 | root->left->left = newNode(40); 112 | root->left->left->left = newNode(30); 113 | root->left->left->left->left = newNode(20); 114 | 115 | root = search(root, 20); 116 | preOrder(root); 117 | return 0; 118 | } -------------------------------------------------------------------------------- /algorithms/stable_marriage_problem.cpp: -------------------------------------------------------------------------------- 1 | /* Ignore the dirty comments */ 2 | #define MAX 100001 3 | 4 | int prefM[MAX][MAX], rankW[MAX][MAX], options[MAX], marriedTo[MAX]; 5 | queue bachelor; 6 | int N; 7 | 8 | void stableMarriage() { 9 | memset(marriedTo, -1, sizeof marriedTo); 10 | 11 | int man, woman, husband; 12 | 13 | // while there is a free man m who still has a woman to propose to 14 | while(!bachelor.empty()) { 15 | man = bachelor.front(); 16 | bachelor.pop(); 17 | bool friendZoned = true; 18 | for(int j = options[man] - 1; j >= 0; --j) { 19 | // man's highest ranked such woman to whom he has not yet proposed 20 | woman = prefM[man][j]; 21 | // man won't propose this woman again 22 | options[man]--; 23 | 24 | // if this woman is free 25 | if(marriedTo[woman] == -1) { 26 | // man and woman become engaged 27 | marriedTo[woman] = man; 28 | // man is no longer friend, so stop 29 | friendZoned = false; 30 | break; 31 | } else { // if woman is already engaged 32 | husband = marriedTo[woman]; 33 | // if woman prefers man to husband (bitch) 34 | if(rankW[woman][man] > rankW[woman][husband]) { 35 | // woman divorces her husband and man-woman get engaged 36 | marriedTo[woman] = man; 37 | 38 | // welcome to friendzone, you miserable bastard! :3) 39 | bachelor.push(husband); 40 | 41 | // man is no longer friend, so stop 42 | friendZoned = false; 43 | break; 44 | } 45 | } 46 | } 47 | // if man got his dick still dry, push the loser into frinedzone again 48 | if(friendZoned) bachelor.push(man); 49 | } 50 | } 51 | 52 | /* 53 | Problem: http://www.codechef.com/problems/STABLEMP (Classical Stable Marriage problem) 54 | */ 55 | 56 | int main(void) { 57 | int tcase; 58 | scanf("%d", &tcase); 59 | int man, woman; 60 | while(tcase--) { 61 | scanf("%d", &N); 62 | for(int i = 1; i <= N; i++) { 63 | scanf("%d", &woman); 64 | for(int j = N - 1; j >= 0; j--) { 65 | scanf("%d", &man); 66 | rankW[woman][man] = j; 67 | } 68 | } 69 | for(int i = 1; i <= N; i++) { 70 | scanf("%d", &man); 71 | bachelor.push(man); 72 | options[man] = N; 73 | for(int j = N - 1; j >= 0; j--) { 74 | scanf("%d", &prefM[man][j]); 75 | } 76 | } 77 | stableMarriage(); 78 | for(int i = 1; i <= N; i++) { 79 | printf("%d %d\n", marriedTo[i], i); 80 | } 81 | } 82 | return EXIT_SUCCESS; 83 | } 84 | -------------------------------------------------------------------------------- /algorithms/stack.cpp: -------------------------------------------------------------------------------- 1 | #ifndef stack_H 2 | #define stack_H 3 | 4 | #include 5 | 6 | template 7 | class stack { 8 | 9 | struct Node { 10 | T data; 11 | Node* next; 12 | 13 | Node(T const& data, Node* next) 14 | : data(data) 15 | , next(next) { 16 | } 17 | 18 | Node(T&& data, Node* next) 19 | : data(std::move(data)) 20 | , next(next) { 21 | } 22 | }; 23 | 24 | public: 25 | ~stack(); 26 | void push(T const& data); 27 | void push(T&& data); 28 | bool empty() const; 29 | int size() const; 30 | T top() const; 31 | void pop(); 32 | void print(std::ostream& str = std::cout) const; 33 | 34 | 35 | private: 36 | Node* head = nullptr; 37 | int elements = 0; 38 | }; 39 | 40 | template 41 | stack::~stack() { 42 | Node* next; 43 | for(Node* loop = head; loop != nullptr; loop = next) { 44 | next = loop->next; 45 | delete loop; 46 | } 47 | } 48 | template 49 | void stack::push(T const& data) { 50 | head = new Node(data, head); 51 | ++elements; 52 | } 53 | template 54 | void stack::push(T&& data) { 55 | head = new Node(std::move(data), head); 56 | ++elements; 57 | } 58 | template 59 | bool stack::empty() const { 60 | return head == nullptr; 61 | } 62 | template 63 | int stack::size() const { 64 | return elements; 65 | } 66 | template 67 | T stack::top() const { 68 | if (head == nullptr) { 69 | throw std::runtime_error("Invalid Action"); 70 | } 71 | return head->data; 72 | } 73 | template 74 | void stack::pop() { 75 | if (head == nullptr) { 76 | throw std::runtime_error("Invalid Action"); 77 | } 78 | Node* tmp = head; 79 | head = head->next; 80 | --elements; 81 | delete tmp; 82 | } 83 | template 84 | void stack::print(std::ostream& str) const { 85 | int id = 0; 86 | for(Node* loop = head; loop != nullptr; loop = loop->next, ++id) { 87 | str << "Element: " << id << " = " << loop->data << "\n"; 88 | } 89 | } 90 | 91 | #endif -------------------------------------------------------------------------------- /algorithms/subset_sum.cpp: -------------------------------------------------------------------------------- 1 | // Returns true if there is a subset of set[] with sun equal to given sum 2 | bool isSubsetSum(vector& set, int sum) 3 | { 4 | // The value of subset[i][j] will be true if there is a subset of set[0..j-1] 5 | // with sum equal to i 6 | int n = (int)set.size(); 7 | vector> dp(sum + 1, vector(n)); 8 | 9 | // If sum is 0, then answer is true 10 | for (int i = 0; i < n; i++) dp[0][i] = true; 11 | 12 | // If sum is not 0 and set is empty, then answer is false 13 | for (int i = 1; i <= sum; i++) dp[i][0] = false; 14 | 15 | // Fill the subset table in botton up manner 16 | for (int i = 1; i <= sum; i++) { 17 | for (int j = 0; j < n; j++) { 18 | dp[i][j] = dp[i][j - 1]; 19 | if (i - set[j] >= 0) { 20 | dp[i][j] = dp[i][j] | dp[i - set[j]][j - 1]; 21 | } 22 | } 23 | } 24 | 25 | /* 26 | // uncomment this code to print table 27 | for (int i = 0; i <= sum; i++) { 28 | for (int j = 0; j <= n; j++) 29 | printf ("%4d", subset[i][j]); 30 | printf("\n"); 31 | } 32 | */ 33 | 34 | return dp[sum][n]; 35 | } -------------------------------------------------------------------------------- /algorithms/suffix_automata.cpp: -------------------------------------------------------------------------------- 1 | #define maxN 250005 2 | #define maxState (maxN << 1) 3 | #define ASCII 128 4 | 5 | // Necessary to calculate longest common substring in linear time where suffix array yields TLE 6 | 7 | struct State { 8 | State *next[ASCII]; // //Links to next transition state in the DAWG (Directed acyclic word graph) 9 | State *suffix; // //Link to previous transition state in the DAWG 10 | int depth, id; 11 | // long long cnt; 12 | }; 13 | State pool[maxState]; // pool of states, from where you can pick a raw state to include in the DAWG 14 | State *point, *root, *sink; 15 | int size; // number of states present in the DAWG. 16 | 17 | State *newState(int dep) { 18 | point->id = size++; 19 | point->depth = dep; 20 | return point++; 21 | } 22 | 23 | void init() { 24 | point = pool; 25 | size = 0; 26 | root = sink = newState(0); 27 | } 28 | 29 | void extend(int a) { 30 | State *p = newState(sink->depth + 1); 31 | State *cur = sink, *sufState; 32 | while (cur and !cur->next[a]) { 33 | cur->next[a] = p; 34 | cur = cur->suffix; 35 | } 36 | if (!cur) 37 | sufState = root; 38 | else { 39 | State *q = cur->next[a]; 40 | if (q->depth == cur->depth + 1) 41 | sufState = q; 42 | else { 43 | State *r = newState(cur->depth+1); 44 | memcpy(r->next, q->next, sizeof(q->next)); 45 | r->suffix = q->suffix; 46 | q->suffix = r; 47 | sufState = r; 48 | while (cur and cur->next[a] == q) { 49 | cur->next[a] = r; 50 | cur = cur->suffix; 51 | } 52 | } 53 | } 54 | p->suffix = sufState; 55 | sink = p; 56 | } 57 | 58 | 59 | int LCSubstr(string const& S1, string const& S2) { 60 | init(); 61 | int len = (int)S1.length(); 62 | for (int i = 0; i < len; i++) 63 | extend(S1[i]-'a'); 64 | 65 | len = (int)S2.length(); 66 | int indx = 0, length = 0, Max = 0; 67 | State *cur = root; 68 | for (int i = 0; i < len; i++) { 69 | if (cur->next[S2[i] - 'a']) { 70 | length++; 71 | cur = cur->next[S2[i] - 'a']; 72 | } else { 73 | while (cur and !cur->next[S2[i] - 'a']) 74 | cur = cur->suffix; 75 | 76 | if (!cur) { 77 | cur = root; 78 | length = 0; 79 | } else { 80 | length = cur->depth + 1; 81 | cur = cur->next[S2[i] - 'a']; 82 | } 83 | } 84 | if(length > Max) { 85 | Max = length; 86 | indx = i - length + 1; 87 | } 88 | } 89 | 90 | if(Max > 0) 91 | pf("%s\n", S2.substr(indx, Max).c_str()); 92 | 93 | return Max; // len 94 | } -------------------------------------------------------------------------------- /algorithms/suffix_lcp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Suffix array O(n lg^2 n) 3 | LCP table O(n) 4 | Explanation on how suffix array works: http://stackoverflow.com/a/17763563/1162233 5 | */ 6 | 7 | #define Max 1000 8 | string S; 9 | int N, gap; 10 | int sa[Max]; // suffix array 11 | // rank-lookup table(contains the lexicographic names) 12 | // pos[k] contains the lexicographic name of the k-th m-gram of the previous step 13 | int pos[Max]; 14 | // tmp[] is an auxiliary array used to help create pos[] 15 | int tmp[Max]; 16 | int lcp[Max]; 17 | 18 | bool sufCmp(int i, int j) { 19 | if (pos[i] != pos[j]) 20 | return pos[i] < pos[j]; 21 | i += gap; 22 | j += gap; 23 | return (i < N and j < N) ? pos[i] < pos[j] : i > j; 24 | } 25 | 26 | void buildSA() { 27 | N = S.length(); 28 | /* This is a loop that initializes sa[] and pos[]. 29 | For sa[] we assume the order the suffixes have 30 | in the given string. For pos[] we set the lexicographic 31 | rank of each 1-gram using the characters themselves. 32 | That makes sense, right? */ 33 | rep(i, N) sa[i] = i, pos[i] = S[i]; 34 | 35 | /* Gap is the length of the m-gram in each step, divided by 2. 36 | We start with 2-grams, so gap is 1 initially. It then increases 37 | to 2, 4, 8 and so on. */ 38 | for (gap = 1;; gap *= 2) { 39 | /* We sort by (gap*2)-grams: */ 40 | sort(sa, sa + N, sufCmp); 41 | 42 | /* We compute the lexicographic renaming(rank) of each m-gram 43 | that we have sorted above. Notice how the rank is computed 44 | by comparing each n-gram at position i with its 45 | neighbor at i+1. If they are identical, the comparison 46 | yields 0, so the rank does not increase. Otherwise the 47 | comparison yields 1, so the rank increases by 1. */ 48 | rep(i, N - 1) tmp[i + 1] = tmp[i] + sufCmp(sa[i], sa[i + 1]); 49 | 50 | /* tmp contains the rank by position. Now we map this 51 | into pos, so that in the next step we can look it 52 | up per m-gram, rather than by position. */ 53 | rep(i, N) pos[sa[i]] = tmp[i]; 54 | 55 | /* If the largest lexicographic name generated is 56 | n-1, we are finished, because this means all 57 | m-grams must have been different. */ 58 | if (tmp[N - 1] == N - 1) break; 59 | } 60 | } 61 | 62 | void buildLCP() { 63 | for (int i = 0, k = 0; i < N; ++i) 64 | if (pos[i] != N - 1) { 65 | for (int j = sa[pos[i] + 1]; S[i + k] == S[j + k];) ++k; 66 | lcp[pos[i]] = k; 67 | if(k) --k; 68 | } 69 | } 70 | /* 71 | Suffix Array O(nlogn) 72 | Source: Competitive Programming by Felix Halim 73 | */ 74 | 75 | #define MAX 10050 76 | int RA[MAX], tempRA[MAX]; // rank array and temporary rank array 77 | int SA[MAX], tempSA[MAX]; // suffix array and temporary suffix array 78 | int C[MAX]; // for counting/radix sort 79 | // Ph[i] stores the suffix index of the previous suffix of suffix SA[i] in suffix array order 80 | // PLCP - permuted longest common prefix 81 | int Phi[MAX], PLCP[MAX], LCP[MAX]; 82 | 83 | void suffix_sort(int n, int k) { 84 | mem(C, 0); // clear frequency table 85 | 86 | for (int i = 0; i < n; i++) // count the frequency of each rank 87 | C[i + k < n ? RA[i + k] : 0]++; 88 | 89 | int sum = 0, N = max(256, n); // upto 255 ASCII chars or length of n 90 | for (int i = 0; i < N; i++) { 91 | int t = C[i]; 92 | C[i] = sum; 93 | sum += t; 94 | } 95 | 96 | for (int i = 0; i < n; i++) // shuffle the suffix array if necessary 97 | tempSA[C[SA[i] + k < n ? RA[SA[i] + k] : 0]++] = SA[i]; 98 | 99 | memcpy(SA, tempSA, n*sizeof(int)); // update the suffix array 100 | } 101 | 102 | void suffix_array(string &s) { 103 | int n = s.size(); 104 | 105 | // initial rankings 106 | for (int i = 0; i < n; i++) 107 | RA[i] = s[i] - '$'; 108 | 109 | // initial SA {0, 1, 2, ...... n - 1} 110 | for (int i = 0; i < n; i++) 111 | SA[i] = i; 112 | 113 | // repeat sorting process log n times 114 | for (int k = 1; k < n; k *= 2) { 115 | suffix_sort(n, k); // radix sort. sort based on the second item 116 | suffix_sort(n, 0); // then stable sort. 117 | 118 | int r = tempRA[SA[0]] = 0; // re-ranking. start from rank r = 0 119 | for (int i = 1; i < n; i++) { // compare adjacent suffixes 120 | 121 | // if same pair, then same rank r; otherwise increase r 122 | int s1 = SA[i], s2 = SA[i - 1]; 123 | bool equal = true; 124 | equal &= RA[s1] == RA[s2]; 125 | equal &= RA[s1 + k] == RA[s2 + k]; 126 | tempRA[SA[i]] = equal ? r : ++r; 127 | } 128 | 129 | memcpy(RA, tempRA, n * sizeof tempRA[0]); // update the rank array RA 130 | } 131 | } 132 | 133 | void Lcp(string &s) { 134 | int n = s.size(); 135 | 136 | Phi[SA[0]] = -1; // default value i.e. there is no previous suffix that preceed suffix SA[0] 137 | for (int i = 1; i < n; i++) // compute Phi in O(n) 138 | Phi[SA[i]] = SA[i - 1]; // remember which suffix is behind this suffix 139 | 140 | for (int i = 0, L = 0; i < n; i++) { // compute permutated LCP in O(n) 141 | if (Phi[i] == -1) { // special case 142 | PLCP[i] = 0; 143 | continue; 144 | } 145 | // L will be increased max n times 146 | while (s[i + L] == s[Phi[i] + L]) 147 | L++; 148 | 149 | PLCP[i] = L; 150 | // At least (L - 1) characters can match as the next suffix in position order will have one less starting 151 | // character than the current suffix. L will be decreased max n times 152 | L = max(L - 1, 0); 153 | } 154 | 155 | for (int i = 1; i < n; i++) // compute LCP in O(n) 156 | LCP[i] = PLCP[SA[i]]; // put the permutate LCP back to the correct position 157 | } 158 | 159 | int main(void) { 160 | cin >> S; 161 | S += '$'; 162 | pf("O(n logn^2)\n"); 163 | buildSA(); 164 | buildLCP(); 165 | rep(i, N - 1) print(sa[i]), println(lcp[i]); 166 | pf("O(nlogn)\n"); 167 | suffix_array(S); 168 | Lcp(S); 169 | rep(i, N - 1) print(SA[i]), println(LCP[i + 1]); 170 | return 0; 171 | } -------------------------------------------------------------------------------- /algorithms/ternary_search_tree.cpp: -------------------------------------------------------------------------------- 1 | // C program to demonstrate Ternary Search Tree (TST) insert, travese 2 | // and search operations 3 | 4 | // A node of ternary search tree 5 | struct Node { 6 | char data; 7 | 8 | // True if this character is last character of one of the words 9 | unsigned isEndOfString: 1; 10 | 11 | struct Node *left, *eq, *right; 12 | }; 13 | 14 | // A utility function to create a new ternary search tree node 15 | struct Node* newNode(char data) { 16 | struct Node* temp = (struct Node*) malloc(sizeof( struct Node )); 17 | temp->data = data; 18 | temp->isEndOfString = 0; 19 | temp->left = temp->eq = temp->right = NULL; 20 | return temp; 21 | } 22 | 23 | // Function to insert a new word in a Ternary Search Tree 24 | void insert(struct Node** root, char *word) { 25 | // Base Case: Tree is empty 26 | if (!(*root)) 27 | *root = newNode(*word); 28 | 29 | // If current character of word is smaller than root's character, 30 | // then insert this word in left subtree of root 31 | if ((*word) < (*root)->data) 32 | insert(&( (*root)->left ), word); 33 | 34 | // If current character of word is greate than root's character, 35 | // then insert this word in right subtree of root 36 | else if ((*word) > (*root)->data) 37 | insert(&( (*root)->right ), word); 38 | 39 | // If current character of word is same as root's character, 40 | else { 41 | if (*(word + 1)) 42 | insert(&( (*root)->eq ), word + 1); 43 | 44 | // the last character of the word 45 | else 46 | (*root)->isEndOfString = 1; 47 | } 48 | } 49 | 50 | // A recursive function to traverse Ternary Search Tree 51 | void traverseTSTUtil(struct Node* root, char* buffer, int depth) { 52 | if (root) { 53 | // First traverse the left subtree 54 | traverseTSTUtil(root->left, buffer, depth); 55 | 56 | // Store the character of this node 57 | buffer[depth] = root->data; 58 | if (root->isEndOfString) { 59 | buffer[depth + 1] = '\0'; 60 | printf( "%s\n", buffer); 61 | } 62 | 63 | // Traverse the subtree using equal pointer (middle subtree) 64 | traverseTSTUtil(root->eq, buffer, depth + 1); 65 | 66 | // Finally Traverse the right subtree 67 | traverseTSTUtil(root->right, buffer, depth); 68 | } 69 | } 70 | 71 | // The main function to traverse a Ternary Search Tree. 72 | // It mainly uses traverseTSTUtil() 73 | void traverseTST(struct Node* root) { 74 | char buffer[MAX]; 75 | traverseTSTUtil(root, buffer, 0); 76 | } 77 | 78 | // Function to search a given word in TST 79 | int searchTST(struct Node *root, char *word) { 80 | if (!root) 81 | return 0; 82 | 83 | if (*word < (root)->data) 84 | return searchTST(root->left, word); 85 | 86 | else if (*word > (root)->data) 87 | return searchTST(root->right, word); 88 | 89 | else { 90 | if (*(word + 1) == '\0') 91 | return root->isEndOfString; 92 | 93 | return searchTST(root->eq, word + 1); 94 | } 95 | } 96 | 97 | int main() { 98 | struct Node *root = NULL; 99 | 100 | insert(&root, "cat"); 101 | insert(&root, "cats"); 102 | insert(&root, "up"); 103 | 104 | traverseTST(root); 105 | 106 | searchTST(root, "cats")? printf("Found\n"): printf("Not Found\n");\ 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /algorithms/topsort.cpp: -------------------------------------------------------------------------------- 1 | // works but visit same node twice in case like (1->2, 1->3, 3->2) 2 | bool hasLoop(int node, vector>& adj, vector& marked) { 3 | if(marked[node]) { 4 | return true; 5 | } 6 | marked[node] = true; 7 | for(int i = 0; i < (int)adj[node].size(); ++i) { 8 | int neigh = adj[node][i]; 9 | if(hasLoop(neigh, adj, marked)) { 10 | return true; 11 | } 12 | } 13 | marked[node] = false; 14 | return false; 15 | } 16 | 17 | 18 | // The Cormen way 19 | enum {WHITE, GRAY, BLACK}; 20 | 21 | bool hasLoop2(int node, vector>& adj, vector& color) { 22 | if(color[node] == BLACK) { 23 | return false; 24 | } 25 | if(color[node] == GRAY) { 26 | return true; 27 | } 28 | color[node] = GRAY; 29 | for(int i = 0; i < (int)adj[node].size(); ++i) { 30 | int neigh = adj[node][i]; 31 | // if self loop allowed 32 | // if(neigh == node) continue; 33 | if(hasLoop2(neigh, adj, color)) { 34 | return true; 35 | } 36 | } 37 | color[node] = BLACK; 38 | 39 | return false; 40 | } 41 | 42 | void topsortUtil(int u, vector>& adj, vector& visited, vector& result 43 | /*, vector& parent, vector& discover, vector& finish, int& time */) { 44 | visited[u] = true; 45 | // discover[u] = ++time; 46 | for(int i = 0; i < (int)adj[u].size(); i++) { 47 | if(!visited[adj[u][i]]) { 48 | // parent[adj[u][i]] = u; 49 | topsortUtil(adj[u][i], adj, visited, result/*, parent, discover, finish, time */); 50 | } 51 | } 52 | result.push_back(u); 53 | // finish[u] = ++time; 54 | } 55 | 56 | void topsort(int n, vector>& adj, vector& result) { 57 | vector visited(n + 1, false); 58 | for(int i = 0; i < n; i++) { 59 | if(!visited[i]) { 60 | topsortUtil(i, adj, visited, result); 61 | } 62 | } 63 | // reverse(result.begin(), result.end()); 64 | } -------------------------------------------------------------------------------- /algorithms/tsp.cpp: -------------------------------------------------------------------------------- 1 | #define CITY 3 2 | #define INF (1 << 30) 3 | bool visited [CITY] [1 << CITY]; // is_visited 4 | int dp [CITY] [1 << CITY]; // cost at particular state 5 | // path cost - weight[i][j] denotes cost for travel from city i to j 6 | int weight [CITY] [CITY] = { {0, 2, 3}, 7 | {19, 0, 6}, 8 | {7, 8, 0} 9 | }; 10 | 11 | int target = (1 << CITY) - 1; 12 | int origin; 13 | 14 | pair trace[CITY][(1 << CITY) + 1]; 15 | 16 | bool Check(int N, int pos) { 17 | return (bool)(N & (1 << pos)); 18 | } 19 | 20 | int Set(int N, int pos) { 21 | return N | (1 << pos); 22 | } 23 | 24 | int tspBitmask (int node, int mask) { 25 | if ( mask == target ) { // all visited 26 | visited [node] [mask] = true; 27 | trace[node][mask] = make_pair(origin, weight[node] [origin]); 28 | return dp [node] [mask] = weight[node] [origin]; 29 | } 30 | 31 | if ( visited [node] [mask] ) 32 | return dp [node] [mask]; 33 | visited [node] [mask] = true; 34 | 35 | int ans = INF, v, cost; 36 | 37 | for ( int i = 0; i < CITY; i++ ) { 38 | if ( !Check(mask, i) ) { 39 | int ret = tspBitmask (i, Set(mask, i) ); 40 | if (ret + weight [node][i] < ans) { 41 | ans = ret + weight [node][i]; 42 | v = i; 43 | cost = weight[node][i]; 44 | } 45 | } 46 | } 47 | trace[node][mask] = make_pair(v, cost); 48 | 49 | return dp [node] [mask] = ans; 50 | } 51 | 52 | void printPath() { 53 | memset (visited, false, sizeof visited); 54 | origin = 0; 55 | printf ("%d\n", tspBitmask (origin, (1 << origin) )); 56 | int mask = 0; 57 | mask |= (1 << origin); 58 | int u = origin, v, cost; 59 | for (int i = 0; i < CITY; i++) { 60 | v = trace[u][mask].first; 61 | cost = trace[u][mask].second; 62 | printf("%d %d %d\n", u, v, cost); 63 | mask |= (1 << v); 64 | u = v; 65 | } 66 | } -------------------------------------------------------------------------------- /algorithms/union_find.cpp: -------------------------------------------------------------------------------- 1 | vector pset, Rank; 2 | 3 | void initSet(int _size) { 4 | pset.resize(_size); 5 | Rank.resize(_size); 6 | for(int i = 0; i < _size; ++i) { 7 | pset[i] = i; 8 | Rank[i] = i; 9 | } 10 | } 11 | 12 | int findSet(int u) { 13 | return (pset[u] == u) ? u : (pset[u] = findSet(pset[u])); // path compression 14 | } 15 | 16 | void unionSet(int u, int v) { 17 | int Pu = findSet(u), Pv = findSet(v); 18 | if(Pu == Pv) return; 19 | 20 | if(Rank[Pu] > Rank[Pv]) 21 | pset[Pv] = Pu; 22 | else { 23 | pset[Pu] = Pv; 24 | } 25 | if(Rank[Pu] == Rank[Pv]) { 26 | Rank[Pv]++; 27 | } 28 | } 29 | 30 | bool isSameSet(int u, int v) { 31 | return findSet(u) == findSet(v); 32 | } -------------------------------------------------------------------------------- /algorithms/vector.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class Vector { 3 | public: 4 | 5 | typedef T* iterator; 6 | 7 | Vector(); 8 | Vector(size_t size); 9 | Vector(size_t size, const T & initial); 10 | Vector(const Vector& v); 11 | ~Vector(); 12 | 13 | Vector & operator = (const Vector &); 14 | 15 | size_t capacity() const; 16 | size_t size() const; 17 | bool empty() const; 18 | 19 | const iterator begin() const; 20 | iterator begin(); 21 | 22 | const iterator end() const; 23 | iterator end(); 24 | 25 | // both form should be implemented otherwise some STL functions won't work 26 | const T& front() const; 27 | T& front(); 28 | 29 | const T& back() const; 30 | T& back(); 31 | 32 | void push_back(const T& value); 33 | void pop_back(); 34 | 35 | void reserve(size_t capacity); 36 | void resize(size_t size); 37 | 38 | T & operator[](size_t index) const; 39 | 40 | void clear(); 41 | private: 42 | size_t _size; 43 | size_t _capacity; 44 | T* buffer; 45 | }; 46 | 47 | template 48 | Vector::Vector() { 49 | _capacity = 0; 50 | _size = 0; 51 | buffer = 0; 52 | } 53 | 54 | template 55 | Vector::Vector(const Vector & v) { 56 | _size = v._size; 57 | _capacity = v._capacity; 58 | buffer = new T[_size]; 59 | copy(v.buffer, v.buffer + _size, buffer); 60 | } 61 | 62 | template 63 | Vector::Vector(size_t size) { 64 | _size = size; 65 | _capacity = size; 66 | buffer = new T[_capacity]; 67 | } 68 | 69 | template 70 | bool Vector:: empty() const { 71 | return _size == 0; 72 | } 73 | 74 | template 75 | Vector::Vector(size_t size, const T& initial) { 76 | _size = size; 77 | _capacity = size; 78 | buffer = new T [_capacity]; 79 | fill(buffer, buffer + _size, initial); 80 | } 81 | 82 | template 83 | Vector& Vector::operator = (const Vector & v) { 84 | free(buffer); 85 | _size = v._size; 86 | _capacity = v._capacity; 87 | buffer = new T [_capacity]; 88 | copy(v.buffer, v.buffer + _size, buffer); 89 | return *this; 90 | } 91 | 92 | template 93 | const typename Vector::iterator Vector::begin() const { 94 | return buffer; 95 | } 96 | 97 | template 98 | typename Vector::iterator Vector::begin() { 99 | return buffer; 100 | } 101 | 102 | template 103 | const typename Vector::iterator Vector::end() const { 104 | return buffer + _size; 105 | } 106 | 107 | template 108 | typename Vector::iterator Vector::end() { 109 | return buffer + _size; 110 | } 111 | 112 | template 113 | const T& Vector::front() const { 114 | return buffer[0]; 115 | } 116 | 117 | 118 | template 119 | T& Vector::front() { 120 | return buffer[0]; 121 | } 122 | 123 | template 124 | const T& Vector::back() const { 125 | return buffer[_size - 1]; 126 | } 127 | 128 | template 129 | T& Vector::back() { 130 | return buffer[_size - 1]; 131 | } 132 | 133 | template 134 | void Vector::push_back(const T & v) { 135 | /* 136 | Incidentally, one common way of regrowing an array is to double the size as needed. 137 | This is so that if you are inserting n items at most only O(log n) regrowths are performed 138 | and at most O(n) space is wasted. 139 | */ 140 | if (_size >= _capacity) { 141 | if(_capacity == 0) 142 | reserve(_capacity + 1); 143 | else 144 | reserve(_capacity * 2); 145 | } 146 | buffer [_size++] = v; 147 | } 148 | 149 | template 150 | void Vector::pop_back() { 151 | (reinterpret_cast(buffer)[_size - 1]).~T(); 152 | _size--; 153 | } 154 | 155 | template 156 | void Vector::reserve(size_t capacity) { 157 | T* newBuffer = new T[capacity]; 158 | 159 | copy(buffer, buffer + _size, newBuffer); 160 | 161 | _capacity = capacity; 162 | free(buffer); 163 | buffer = newBuffer; 164 | } 165 | 166 | template 167 | size_t Vector::size() const { 168 | return _size; 169 | } 170 | 171 | template 172 | void Vector::resize(size_t size) { 173 | reserve(size); 174 | _size = size; 175 | } 176 | 177 | template 178 | T& Vector::operator[](size_t index) const { 179 | return buffer[index]; 180 | } 181 | 182 | template 183 | size_t Vector::capacity() const { 184 | return _capacity; 185 | } 186 | 187 | template 188 | Vector::~Vector() { 189 | free(buffer); 190 | } -------------------------------------------------------------------------------- /algorithms/z.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | Z[i] is the length of the longest common prefix between s and the suffix of s starting at i. 3 | Example: 4 | s = 'aaabaab' 5 | 6 | z[0] = 0, 7 | z[1] = 2, 8 | z[2] = 1, 9 | z[3] = 0, 10 | z[4] = 2, 11 | z[5] = 1, 12 | z[6] = 0. 13 | s = 'abacaba' 14 | 15 | z[0] = 0, 16 | z[1] = 0, 17 | z[2] = 1, 18 | z[3] = 0, 19 | z[4] = 3, 20 | z[5] = 0, 21 | z[6] = 1. 22 | 23 | Applications: 24 | 1. searching substring: find all occurances of pattern in O(n) + O(m) time 25 | 2. find all unique substrings of strings 26 | 3. string compression: find a string t of shortest length such that s can be represented as a concatenation of one or more copies of t. 27 | 28 | See: https://www.hackerrank.com/challenges/string-similarity/topics/z-function 29 | ***/ 30 | 31 | vector Z; 32 | 33 | // O(n) 34 | void zFunction(string const& s) { 35 | int n = (int) s.length(); 36 | Z = vector(n); 37 | for(int i = 1, left = 0, right = 0; i < n; ++i) { 38 | if (i <= right) { 39 | Z[i] = min (right - i + 1, Z[i - left]); 40 | } 41 | while (i + Z[i] < n && s[Z[i]] == s[i + Z[i]]) { 42 | ++Z[i]; 43 | } 44 | if (i + Z[i] - 1 > right) { 45 | left = i; 46 | right = i + Z[i] - 1; 47 | } 48 | } 49 | } --------------------------------------------------------------------------------