├── Chapter 05: Complete Search ├── Part1 : Generating Subsets │ ├── generatingsubsets_method1.cpp │ └── generatingsubsets_method2.cpp ├── Part2 : Generating Permutations │ ├── generatingpermutations_functionimplementation.cpp │ ├── generatingpermutations_method1.cpp │ └── generatingpermutations_method2.cpp └── Part3 : BackTracking │ └── backtracking_nqueen.cpp ├── Chapter 06: Greedy ├── greedy_coins.cpp ├── greedy_maxjobs.cpp ├── greedy_minimisingsums.cpp └── greedy_tasksanddeadline.cpp ├── Chapter 07: Dynamic Programming ├── dp_coinproblem_countingsolutions.cpp ├── dp_coinproblem_iterative.cpp ├── dp_coinproblem_iterative_printing.cpp ├── dp_coinproblem_memoisation.cpp ├── dp_editdistance_recurrsive.cpp ├── dp_knapsack_iterative_2d.cpp ├── dp_longestincreasingsubsequence.cpp ├── dp_longestincreasingsubsequence_nlogn.cpp ├── dp_pathsingrid_iterative.cpp └── dp_pathsingrid_recurrsive.cpp ├── Chapter 08: Amortized Analysis ├── Part1: Two Pointer Method │ ├── twopointer_2sum.cpp │ └── twopointer_subarray_sum.cpp ├── amorted_analysis_nearest_smaller_element.cpp └── amortized_analysis_slidingwindowminimum.cpp ├── Chapter 09: Range Queries ├── rq_bit.cpp ├── rq_prefixsum.cpp ├── rq_segmenttree.cpp └── rq_sparsetables.cpp ├── Chapter 12: Graph Traversal ├── graphtraversal_bfs.cpp ├── graphtraversal_bipartitecheck.cpp └── graphtraversal_dfs.cpp ├── Chapter 13: Shortest Paths ├── shortestpaths_bellman.cpp ├── shortestpaths_bellman_pathretrieval.cpp ├── shortestpaths_dijkstra.cpp ├── shortestpaths_dijkstra_paths.cpp └── shortestpaths_floydwarshall.cpp ├── Chapter 14: Tree Algorithms ├── treetraversal_dfs.cpp ├── treetraversal_diameter.cpp └── treetraversal_subtreecardinality.cpp ├── Chapter 15: Spanning Trees ├── spanningtree_kruskals.cpp ├── spanningtree_prims.cpp └── spanningtree_unionfind1.cpp ├── Chapter 16: Directed Graphs ├── directedgraphs_countingpaths.cpp └── directedgraphs_topologicalsorting.cpp ├── Chapter 17: Strong Connectivity └── strongconnectivity_kosaraju.cpp ├── Chapter 18: Tree Queries ├── treequeries_distancebetween2.cpp ├── treequeries_findingancestor_sparsetable.cpp ├── treequeries_findingancestors.cpp ├── treequeries_findingrangesum.cpp ├── treequeries_lca_method1.1.cpp └── treequeries_lca_method2.cpp ├── Chapter 21: Number Theory ├── Prime Numbers │ ├── primefactor_rootn.cpp │ └── primefactor_sieveoferatosthenes.cpp └── gcd_euclidsalgorithm.cpp ├── LICENSE └── README.md /Chapter 05: Complete Search/Part1 : Generating Subsets/generatingsubsets_method1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | /* Generating Subsets 5 | You are given a set of numbers : {0 , 1 , 2 , 3 , 4} 6 | You have to find all the subsets of this set. 7 | */ 8 | 9 | int n; 10 | int A[100]; 11 | vector ans; 12 | 13 | void search(int k) 14 | { 15 | if(k>=n) 16 | { 17 | //Print the subset 18 | for(int i=0;i> n; 40 | // Input the elements 41 | for(int i=0;i> A[i]; 44 | } 45 | search(0); 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Chapter 05: Complete Search/Part1 : Generating Subsets/generatingsubsets_method2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | /* Generating Subsets : Method 2 5 | You are given a set of numbers : {0 , 1 , 2 , 3 , 4} 6 | You have to find all the subsets of this set. 7 | */ 8 | 9 | int n; 10 | int A[100]; 11 | 12 | void search() 13 | { 14 | // 1 << n means 2^n i.e this number of combinations are possible 15 | // Now 2^n will take n bits 101001... n 16 | // Each xth bit represets the presence of xth number in A[i] 17 | for(int i=0;i< (1<> n; 35 | // Input the elements 36 | for(int i=0;i> A[i]; 39 | } 40 | search(); 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Chapter 05: Complete Search/Part2 : Generating Permutations/generatingpermutations_functionimplementation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | You are given a number n. You have to generate all permutations of list 1,2,....n. 3 | Two ways : 4 | 1. Recursion 5 | 2. Iterative 6 | 7 | Now I will implement next permutation function. 8 | 9 | */ 10 | 11 | #include 12 | using namespace std; 13 | 14 | void nextpermutation(vector &x) 15 | { 16 | for(int i=x.size()-1;i>=1;i--) 17 | { 18 | if(x[i-1] < x[i]) 19 | { 20 | int j=i; 21 | for(j=i;j> n; 43 | vector A; 44 | for(int i=0;i 11 | using namespace std; 12 | 13 | int n; 14 | vector ans; 15 | bool done[100] = {false}; 16 | 17 | void print(vector x) 18 | { 19 | for(int i=0;i= n) 27 | { 28 | print(ans); 29 | } 30 | else 31 | { 32 | for(int i = 0; i < n; i++) 33 | { 34 | if(done[i] == true) continue; 35 | done[i] = true; 36 | ans.push_back(i+1); 37 | solve(); 38 | done[i] = false; 39 | ans.pop_back(); 40 | } 41 | } 42 | } 43 | 44 | 45 | int main() { 46 | cin >> n; 47 | solve(); 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Chapter 05: Complete Search/Part2 : Generating Permutations/generatingpermutations_method2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | You are given a number n. You have to generate all permutations of list 1,2,....n. 3 | Two ways : 4 | 1. Recursion 5 | 2. Iterative 6 | 7 | This code is iterative way of doing this using stl function, next_permutation. 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | vector ans; 14 | 15 | void print(vector x) 16 | { 17 | for(int i=0;i> n; 24 | for(int i=0;i 8 | using namespace std; 9 | 10 | int n; 11 | int m 12 | bool col[100] = {false}; 13 | bool diag[100] = {false}; 14 | bool diag2[100] = {false}; 15 | int A[100][100]; 16 | 17 | void solve(int k) 18 | { 19 | if(k>=n) 20 | { 21 | for(int i=0;i> n; 54 | solve(0); 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Chapter 06: Greedy/greedy_coins.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Coin Problem. 3 | Given coins in euro system : 1, 2, 5, 10 ... Find number of minimum coins to change 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | int coins[4] = {1, 2, 5, 10}; 9 | void solve() 10 | { 11 | int n; 12 | cin >>n; 13 | int ans=0; 14 | for(int i=3;i>=0;i--) 15 | { 16 | ans+=n/coins[i]; 17 | n%=coins[i]; 18 | } 19 | cout << ans << endl; 20 | } 21 | 22 | int main() 23 | { 24 | solve(); 25 | } 26 | -------------------------------------------------------------------------------- /Chapter 06: Greedy/greedy_maxjobs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Max jobs problem. 3 | You are given n jobs with start and end time. Find the maximum number of jobs you can do. 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | 9 | // Jon datastructure that encapsulates start as well as end 10 | struct job 11 | { 12 | int start; 13 | int end; 14 | }; 15 | 16 | // Compare function that is used for sorting 17 | bool comp(job a, job b) 18 | { 19 | if(a.end != b.end) 20 | { 21 | return a.end < b.end; 22 | } 23 | else return a.start < b.start; 24 | } 25 | 26 | // Main function which takes the job as input sorts it and outputs maximum jobs that can be done. 27 | void solve() 28 | { 29 | int n; 30 | cin >> n; 31 | job jobs[n]; 32 | for(int i=0; i < n; i++) 33 | { 34 | int x,y; 35 | cin >> x >> y; 36 | jobs[i].start = x; 37 | jobs[i].end = y; 38 | } 39 | 40 | sort(jobs, jobs+n, comp); 41 | int cnt=0; 42 | for(int i=0;i 8 | using namespace std; 9 | 10 | int A[100]; 11 | void solve() 12 | { 13 | int n; 14 | cin >> n; 15 | for(int i=0; i> A[i]; 18 | } 19 | sort(A,A+n); 20 | int x = A[(n-1)/2]; 21 | cout << x << endl; 22 | } 23 | 24 | int main() { 25 | solve(); 26 | return 0; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Chapter 06: Greedy/greedy_tasksanddeadline.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Max jobs problem. 3 | You are given n jobs with start and end time. Find the maximum number of jobs you can do. 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | 9 | // Jon datastructure that encapsulates start as well as end 10 | struct job 11 | { 12 | int duration; 13 | int deadline; 14 | }; 15 | 16 | // Compare function that is used for sorting 17 | bool comp(job a, job b) 18 | { 19 | if(a.duration != b.duration) 20 | { 21 | return a.duration < b.duration; 22 | } 23 | else return a.deadline < b.deadline; 24 | } 25 | 26 | // Main function which takes the job as input sorts it and outputs maximum jobs that can be done. 27 | void solve() 28 | { 29 | int n; 30 | cin >> n; 31 | job tasks[n]; 32 | for(int i=0;i> x >> y; 36 | tasks[i].duration = x; 37 | tasks[i].deadline = y; 38 | } 39 | sort(tasks, tasks+n, comp); 40 | int curr=0; 41 | int ans=0; 42 | // Do the task with least time to complete first to maximise the profit. 43 | for(int i=0;i 8 | using namespace std; 9 | int n; 10 | // Stores the coins that can be exhanged for a value. 11 | vector coins; 12 | int dp[100000000]; 13 | 14 | // This is iterative function that calls find(sum-c) everytime 15 | int find(int sum) 16 | { 17 | dp[0] = 1; 18 | // First we build smaller solutions i.e 0 , 1 , 2 , 3 and then use them to find the greater solution. 19 | for(int i=0;i<=sum;i++) 20 | { 21 | for(int j=0;j> n; 34 | for(int i=0;i> x; 38 | coins.push_back(x); 39 | } 40 | int sum; 41 | cin >> sum; 42 | cout << find(sum) << endl; 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_coinproblem_iterative.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7 : Dynamic Programming 3 | Topic : Coin Problem 4 | Question : You are given coins of value coins[i] for all i that belong to n. Now find minimum coins to exchange for x. 5 | This is iterative code for the same problem. 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | // imax is value that is biggest and can not actually be exchanged for 11 | int imax = 100000000; 12 | int n; 13 | // Stores the coins that can be exhanged for a value. 14 | vector coins; 15 | int dp[100000000]; 16 | 17 | // This is iterative function that calls find(sum-c) everytime 18 | int find(int sum) 19 | { 20 | dp[0] = 0; 21 | // First we build smaller solutions i.e 0 , 1 , 2 , 3 and then use them to find the greater solution. 22 | for(int i=0;i<=sum;i++) 23 | { 24 | for(int j=0;j> n; 37 | for(int i=0;i> x; 41 | coins.push_back(x); 42 | } 43 | int sum; 44 | cin >> sum; 45 | cout << find(sum) << endl; 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_coinproblem_iterative_printing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7 : Dynamic Programming 3 | Topic : Coin Problem 4 | Question : You are given coins of value coins[i] for all i that belong to n. Now find minimum coins to exchange for x. 5 | This is iterative code for the same problem. 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | // imax is value that is biggest and can not actually be exchanged for 11 | int imax = 100000000; 12 | int n; 13 | // Stores the coins that can be exhanged for a value. 14 | vector coins; 15 | int dp[100000000]; 16 | int choice[10000000]; 17 | 18 | // This is iterative function that calls find(sum-c) everytime 19 | int find(int sum) 20 | { 21 | dp[0] = 0; 22 | choice[0] = 0; 23 | // First we build smaller solutions i.e 0 , 1 , 2 , 3 and then use them to find the greater solution. 24 | for(int i=0;i<=sum;i++) 25 | { 26 | for(int j=0;j dp[i-coins[j]]+1) 30 | { 31 | dp[i] = dp[i-coins[j]]+1; 32 | choice[i] = coins[j]; 33 | } 34 | } 35 | } 36 | return dp[sum]; 37 | } 38 | 39 | int main() { 40 | for(int i=0;i<1000000;i++) dp[i] = imax; 41 | dp[0] = 0; 42 | cin >> n; 43 | for(int i=0;i> x; 47 | coins.push_back(x); 48 | } 49 | int sum; 50 | cin >> sum; 51 | cout << find(sum) << endl; 52 | int curr = sum; 53 | cout << "Choice of coins:" << endl; 54 | while(curr > 0 ) 55 | { 56 | cout << choice[curr] << " "; 57 | curr-=choice[curr]; 58 | } 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_coinproblem_memoisation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7 : Dynamic Programming 3 | Topic : Coin Problem 4 | Question : You are given coins of value coins[i] for all i that belong to n. Now find minimum coins to exchange for x. 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | // imax is value that is biggest and can not actually be exchanged for 10 | int imax = 100000000; 11 | int n; 12 | // Stores the coins that can be exhanged for a value. 13 | vector coins; 14 | int dp[100000000]; 15 | 16 | // This is recurrsive function that calls find(sum-c) everytime 17 | int find(int sum) 18 | { 19 | // Base conditions , is sum < 0 return no possible else if sum == 0 return 0; 20 | if(sum < 0) return imax; 21 | if(sum ==0) return 0; 22 | // If already calculated, return the value saved. 23 | if(dp[sum] != imax) return dp[sum]; 24 | int ans=imax; 25 | // Check for every coin possible. 26 | for(int i=0;i> n; 39 | for(int i=0;i> x; 43 | coins.push_back(x); 44 | } 45 | int sum; 46 | cin >> sum; 47 | cout << find(sum) << endl; 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_editdistance_recurrsive.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Topic: Dynamic Programming 3 | Question: Edit distance between two strings. 4 | Edit distance between two string is dfined as minimum number of moves required to convert one string to other. These moves can be: 5 | 1. Adding a letter (alphabet) 6 | 2. Removing a letter (alphabet) 7 | 3. Modifying an alphabet 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | int dp[1000][1000]; 14 | 15 | string s1,s2; 16 | 17 | int solve(int i,int j) 18 | { 19 | if(dp[i][j] != -1) return dp[i][j]; 20 | if(s1[i-1] == s2[j-1]) dp[i][j] = solve(i-1,j-1); 21 | else dp[i][j] = min(min(solve(i-1,j),solve(i-1,j-1)),solve(i,j-1))+1; 22 | return dp[i][j]; 23 | } 24 | 25 | int main() { 26 | for(int i=0;i<1000;i++) 27 | for(int j=0;j<1000;j++) 28 | { 29 | if(i==0) dp[i][j]=j; 30 | else if(j==0) dp[i][j]=i; 31 | else dp[i][j]=-1; 32 | } 33 | cin >> s1 >> s2; 34 | cout << solve(s1.size(),s2.size()) << endl; 35 | return 0; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_knapsack_iterative_2d.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7: Dynamic Programming 3 | 4 | Question : Knapsack problem 5 | 6 | Given : w1, w2, w3, w4 ... wn 7 | Find all possible sums that can be formed using these wi 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | int n; 14 | int W[10000]; 15 | int dp[1000][1000]; 16 | int sum=0; 17 | 18 | // Set dp[i][j] = 1 if sum j can be formed using i objects 19 | void solve() 20 | { 21 | dp[0][0] = 1; 22 | for(int j=1;j<=n;j++) 23 | { 24 | for(int i=0;i<=sum;i++) 25 | { 26 | if(i-W[j-1] < 0) 27 | { 28 | // If weight of i was possible using j objects set it equal to 1 29 | dp[j][i] = dp[j-1][i]; 30 | continue; 31 | } 32 | // If weight of i was possible before without using jth object 33 | // Or if weight of i-W[j-1] was possible and adding current weight gives i 34 | dp[j][i] = dp[j-1][i-W[j-1]] | dp[j-1][i]; 35 | } 36 | } 37 | } 38 | 39 | int main() { 40 | // Input and Initialisation 41 | cin >> n; 42 | for(int i=0;i> W[i]; 45 | sum+=W[i]; 46 | } 47 | for(int i=0;i<=sum;i++) 48 | { 49 | for(int j=0;j<=n;j++) 50 | { 51 | dp[j][i]=0; 52 | } 53 | } 54 | // Call out the solver 55 | solve(); 56 | 57 | for(int i=0;i<=sum;i++) 58 | if(dp[n][i]) cout << i << " "; 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_longestincreasingsubsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Longest Increasing Subsequence. 3 | You are given an array of size n, find the longest increasing subsequence. 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | int lis[1000001]; 9 | int A[100001]; 10 | int n; 11 | 12 | 13 | // Function that returns the max answer. 14 | int solve() 15 | { 16 | int ans=0; 17 | // O(n^2) loop for checking the max LIS 18 | for(int i=0;i=0;j--) 21 | { 22 | // If this element is less then current ith element, then A[j] < A[i] is a sequence including the sequence having last element as A[j] 23 | if(A[j] < A[i]) 24 | lis[i] = max(lis[i], lis[j]+1); 25 | } 26 | ans=max(ans,lis[i]); 27 | } 28 | return ans; 29 | } 30 | 31 | int main() { 32 | for(int i=0;i<1000001;i++) 33 | lis[i] = 1; 34 | cin >> n; 35 | for(int i=0;i> A[i]; 37 | 38 | cout << solve() << endl; 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_longestincreasingsubsequence_nlogn.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7: Dynamic Programming 3 | 4 | Question : Longest Increasing Subsequence - O(nlogn) 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | int dp[1000001] = {100000000}; 11 | int A[1000001] = {0}; 12 | int n; 13 | 14 | // This function finds the LIS in nlogn 15 | void solve() 16 | { 17 | // Set all the dp to max value and initial as least 18 | dp[0] = -100000000; 19 | for(int i=1;i<=n;i++) dp[i] = 100000000; 20 | 21 | // Loop nlogn 22 | for(int i=0;i A[i] then dp[j] = A[i]. 26 | // That means that we had a LIS of length j and now a new element A[i] > dp[j] has arrived. 27 | auto it = lower_bound(dp,dp+n,A[i]) - dp; 28 | if(dp[it] > A[i] && A[i] > dp[it-1]) 29 | dp[it] = A[i]; 30 | } 31 | int ans=0; 32 | for(int i=0;i<=n;i++) 33 | { 34 | if(dp[i] < 10000000) 35 | ans=i; 36 | } 37 | cout << ans << endl; 38 | } 39 | 40 | int main() { 41 | cin >> n; 42 | for(int i=0;i> A[i]; 44 | solve(); 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_pathsingrid_iterative.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7: Dynamic Programming 3 | 4 | Question : Maximum sum path on grid. You are given an n x n grid with some values , say coins, now you have to find maximum coins that you can pick from the grid. 5 | 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | int A[1000][1000]; 12 | int dp[1000][1000]; 13 | int n; 14 | 15 | long long solve() 16 | { // Notice the traversal, starting from 0,0 , you goto every x,y and check if 17 | // moving to x,y is more profitable from x-1,y or x,y-1 and make the choice 18 | // Thus every x,y have maximum value that can be collected from moving from 0,0 19 | for(int i=0;i> n; 46 | for(int i=0;i> A[i][j]; 55 | 56 | // Call out the solver 57 | cout << solve() << endl; 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /Chapter 07: Dynamic Programming/dp_pathsingrid_recurrsive.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 7: Dynamic Programming 3 | 4 | Question : Maximum sum path on grid. You are given an n x n grid with some values , say coins, now you have to find maximum coins that you can pick from the grid. 5 | 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | int A[1000][1000]; 12 | int dp[1000][1000]; 13 | int n; 14 | 15 | long long solve(int x,int y) 16 | { 17 | if(x < 0 || y < 0) return 0; 18 | if(dp[x][y] != -1) return dp[x][y]; 19 | dp[x][y] = max(solve(x-1,y),solve(x,y-1))+A[x][y]; 20 | return dp[x][y]; 21 | } 22 | 23 | 24 | int main() { 25 | cin >> n; 26 | for(int i=0;i> A[i][j]; 35 | 36 | cout << solve(n-1,n-1) << endl; 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Chapter 08: Amortized Analysis/Part1: Two Pointer Method/twopointer_2sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Topic: Amortized Analysis 3 | Method: Two pointer 4 | Queston: 2SUM 5 | Find if there are two numbers with sum x in nlog(n) 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | int A[10000]; 12 | 13 | bool solve() 14 | { 15 | int n; 16 | cin >> n; 17 | int x; 18 | cin >> x; 19 | for(int i=0;i> A[i]; 20 | //Sort so that we know that larger number is at right and smaller at left. 21 | sort(A,A+n); 22 | int i=0;int j=n-1; 23 | // Here we consider two pointer first at left and second at right. Then we start. 24 | // If sum > x, then reduce the larger number that is at right (j). 25 | // Else if sum < x then increase larger number that is at left (i). 26 | while(i x) 29 | { 30 | j--; 31 | } 32 | else if(A[i]+A[j] < x) 33 | { 34 | i++; 35 | } 36 | else 37 | { 38 | return true; 39 | } 40 | } 41 | return false; 42 | } 43 | 44 | int main() { 45 | int t; 46 | cin >> t; 47 | while(t--) 48 | { 49 | if(solve()) 50 | { 51 | cout << "Yes, exists" << endl; 52 | } 53 | else cout << "No, do not exist" << endl; 54 | } 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Chapter 08: Amortized Analysis/Part1: Two Pointer Method/twopointer_subarray_sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Topic: Amortized Analysis 3 | Method: Two pointer 4 | Queston: Given an array of given size. Find if a contigous subarray have sum equal to x 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | int A[10000]; 11 | 12 | bool solve() 13 | { 14 | int n; 15 | cin >> n; 16 | int x; 17 | cin >> x; 18 | for(int i=0;i> A[i]; 19 | // Starting pointer that moves from left. 20 | int st=0; 21 | int csum=0; 22 | // Second pointer is i, that tells the right extreme. 23 | for(int i=0;i x) 27 | { 28 | while(csum > x && st<=i) 29 | { 30 | csum-=A[st]; 31 | st++; 32 | } 33 | } 34 | if(csum == x) return true; 35 | } 36 | return false; 37 | } 38 | 39 | int main() { 40 | int t; 41 | cin >> t; 42 | while(t--) 43 | { 44 | if(solve()) 45 | { 46 | cout << "Yes, exists" << endl; 47 | } 48 | else cout << "No, Subarray do not exist" << endl; 49 | } 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Chapter 08: Amortized Analysis/amorted_analysis_nearest_smaller_element.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Topic: Amortized Analysis 3 | Datastructure: Stack 4 | Queston: Nearest Smaller Element 5 | Find the closest smaller preceding element. 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | int A[10000]; 12 | 13 | bool solve() 14 | { 15 | int n; 16 | cin >> n; 17 | vector vec; 18 | vector ans(n,-1); 19 | stack st; 20 | for(int i=0;i> x; 24 | vec.push_back(x); 25 | } 26 | for(int i=n-1;i>=0;i--) 27 | { 28 | if(st.empty() || vec[st.top()] <= vec[i]) 29 | st.push(i); 30 | else 31 | { 32 | while(!st.empty() && vec[i] < vec[st.top()]) 33 | { 34 | ans[st.top()] = vec[i]; 35 | st.pop(); 36 | } 37 | st.push(i); 38 | } 39 | } 40 | for(int i=0;i> t; 48 | while(t--) 49 | { 50 | solve(); 51 | } 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Chapter 08: Amortized Analysis/amortized_analysis_slidingwindowminimum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Topic: Amortized Analysis 3 | Datastructure: deque 4 | Queston: Smallest element in a window of size w in o(n). 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | int A[10000]; 11 | int n; 12 | int w = 0; 13 | vector vec; 14 | vector ans; 15 | 16 | void solve() 17 | { 18 | deque deq; 19 | for(int i=0;i w) 23 | { 24 | deq.pop_front(); 25 | } 26 | // If current element is less then the deque last element start poping them till dequeue last element is less than or equal to current element. 27 | if(deq.size() && deq.back() > vec[i]) 28 | { 29 | while(deq.size() && deq.back() > vec[i]) deq.pop_back(); 30 | } 31 | // Push current element. 32 | deq.push_back(vec[i]); 33 | ans.push_back(deq.front()); 34 | } 35 | for(int i=0;i> t; 41 | while(t--) 42 | { 43 | // This part involves inputs only. All these vectors and variables are made global so that I can separate main functionality in solve() function 44 | vec.clear(); 45 | ans.clear(); 46 | cin >> n; 47 | cin >> w; 48 | for(int i=0;i> x; 52 | vec.push_back(x); 53 | } 54 | // Input ends, now solve the answer. 55 | solve(); 56 | } 57 | return 0; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Chapter 09: Range Queries/rq_bit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Range Sum Queries 3 | Concept: Binary Index Tree 4 | You are given an array with elements. Your task is to find sum of a range in O(logn) and update in log(n). 5 | 6 | Explaination: 7 | Every number in index can be represented as a binary number. What we do here is, we make a new array of same size but different way of storing. 8 | 1. Suppose k = 5 then it can be written as 101, thus it will be stored at location 5,6 and 8 only as 101+1 = 110 and 110+010 = 1000 = 8 9 | 2. Now we know that any index i is at i&(-i), using this we will find prefix sum which is just the ith element and all the other element that can be formed by removing the LSB. 10 | */ 11 | 12 | #include 13 | using namespace std; 14 | #define long long LL; 15 | int BIT[10000]; 16 | int A[10000]; 17 | int n; 18 | void add(int k,int x) 19 | { 20 | while(k<=n) 21 | { 22 | BIT[k]+=x; 23 | k+=(k&(-k)); 24 | } 25 | } 26 | 27 | void build() 28 | { 29 | for(int i=1;i<=n;i++) 30 | { 31 | add(i,A[i]); 32 | } 33 | } 34 | 35 | int query(int k) 36 | { 37 | int s=0; 38 | while(k>0) 39 | { 40 | s+=BIT[k]; 41 | k-=(k&(-k)); 42 | } 43 | return s; 44 | } 45 | 46 | void solve() 47 | { 48 | build(); 49 | int q; 50 | cin >> q; 51 | while(q--) 52 | { 53 | int x,y; 54 | cin >> x >> y; 55 | cout << query(y) - query(x-1) << endl; 56 | } 57 | } 58 | 59 | int main() { 60 | cin >> n; 61 | for(int i=1;i<=n;i++) 62 | { 63 | cin >> A[i]; 64 | } 65 | 66 | solve(); 67 | return 0; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Chapter 09: Range Queries/rq_prefixsum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Topic: Range Queries 3 | Technqiue: Prefix sum. 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void solve() 10 | { 11 | int n; int q; 12 | cin >> n >> q; 13 | int A[n]; 14 | int pref[n]; 15 | for(int i=0;i> A[i]; 17 | for(int i=0;i> x >> y; 25 | cout << pref[y] - pref[max(x-1,0)] << endl; 26 | } 27 | } 28 | 29 | int main() { 30 | solve(); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter 09: Range Queries/rq_segmenttree.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Most Basic implementation of segment tree and properly commmented : 3 | 4 | #include 5 | using namespace std; 6 | 7 | // Original Array that stores the input 8 | int A[200000]={INT_MAX}; 9 | // Array that stores the segment tree 10 | int tree[800005] = {INT_MAX}; 11 | 12 | // Segment tree have 3 parts 13 | // 1. Build Tree 14 | // 2. Query the Tree 15 | // 3. Update the tree and array 16 | 17 | // Building tree using recursion 18 | // L = left boundary of the input array 19 | // R = right boundary of the input array 20 | // Now if L==R then this is the leaf for the tree of end of the array 21 | // l>r then it is invalid case 22 | // If not lead, divide the array into two, and save there sum to tree[2*node] and tree[2*node+1] 23 | // Finally save tree[node] = tree[node*2]+tree[node*2+1]; 24 | 25 | void build(int treenode,int l,int r) 26 | { 27 | 28 | if(l==r) {tree[treenode] = A[l];return;} 29 | if(l>r) return; 30 | int mid = (l+r)/2; 31 | build(treenode*2,l,mid); 32 | build(treenode*2+1,mid+1,r); 33 | tree[treenode] = min(tree[treenode*2],tree[treenode*2+1]); 34 | 35 | } 36 | 37 | // Querying the segment tree 38 | // L and R store the range of the segment tree being checked. 39 | // ql and qr the are query ranges 40 | // if L and R are withign the query ranges just return the segment value (why do down?) 41 | // If L and R are outside the query range (not overlaping at all) simply return the int max 42 | // Else if partial overlapping is present, just divide the tree into two sides and traverse 43 | 44 | int query(int node,int l,int r,int ql,int qr) 45 | { 46 | if(l>qr || r= r) return tree[node]; 48 | int mid = (l+r)/2; 49 | int left = query(2*node,l,mid,ql,qr); 50 | int right = query(2*node+1,mid+1,r,ql,qr); 51 | return min(left,right); 52 | } 53 | 54 | // Updating the tree 55 | 56 | void update(int node,int l,int r,int pos,int val) 57 | { 58 | if(l==r){ tree[node]=val,A[pos]=val;return; } 59 | if(l>r) return; 60 | int mid=(l+r)/2; 61 | if(pos>=l && pos<=mid) 62 | update(node*2,l,mid,pos,val); 63 | else update(node*2+1,mid+1,r,pos,val); 64 | tree[node]=min(tree[node*2],tree[node*2+1]); 65 | } 66 | 67 | 68 | 69 | int main() { 70 | 71 | // Taking input 72 | int n,q; 73 | cin >> n >> q; 74 | for(int i=0;i> A[i]; 76 | for(int i=0;i<=4*n+1;i++) tree[i] = INT_MAX; 77 | //------------------------------------- 78 | build(1,0,n-1); 79 | //for(int i=0;i<4*n;i++) cout << tree[i] << " "; 80 | while(q--) 81 | { 82 | char x;int l;int r; 83 | cin >> x >> l >> r; 84 | if(x=='q') 85 | cout << query(1,0,n-1,l-1,r-1) << endl; 86 | else update(1,0,n-1,l-1,r); 87 | } 88 | 89 | } 90 | 91 | -------------------------------------------------------------------------------- /Chapter 09: Range Queries/rq_sparsetables.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Minimum Queries 3 | Concept: Sparse Table 4 | You are given an array with elements. Your task is to find minimum in a given range in O(nlogn). 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | #define long long LL; 10 | int table[10000][10]; 11 | int A[10000]; 12 | int n; 13 | int mxp; 14 | 15 | 16 | // Create Sparse Table 17 | void create_sparse() 18 | { 19 | int p=1; 20 | while(p<=mxp) 21 | { 22 | int len = 1<=0;p--) 38 | { 39 | int len = 1<= len) 41 | { 42 | ans=min(ans,table[x][p]); 43 | x+=len; 44 | } 45 | } 46 | return ans; 47 | } 48 | 49 | int main() { 50 | // Initialization 51 | for(int i=0;i<1000;i++) 52 | for(int j=0;j<10;j++) 53 | table[i][j]=INT_MAX; 54 | cin >> n; 55 | mxp = log2(n)+1; 56 | // Take input 57 | for(int i=1;i<=n;i++) 58 | { 59 | cin >> A[i]; 60 | table[i][0] = A[i]; 61 | } 62 | 63 | // Create sparse table 64 | create_sparse(); 65 | // Input queries 66 | int q; 67 | cin >> q; 68 | while(q--) 69 | { 70 | int x,y; 71 | cin >> x >> y; 72 | cout << query_sparse(x,y) << endl; 73 | } 74 | return 0; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Chapter 12: Graph Traversal/graphtraversal_bfs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 12: Graph Traversal 3 | Topic: Breadth First Search 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | // Adjacency list , lets suppose nodes are less then 1000 9 | vector adj[1000]; 10 | vector vis(1000, 0); 11 | 12 | void bfs(int x) 13 | { 14 | queue q; 15 | q.push(x); 16 | 17 | while(!q.empty()) 18 | { 19 | int y = q.front(); 20 | q.pop(); 21 | vis[y]=true; 22 | for(int i=0;i> n; 34 | int edges; 35 | cin >> edges; 36 | for(int i=0;i> x >> y; 40 | adj[x].push_back(y); 41 | adj[y].push_back(x); 42 | } 43 | bfs(1); 44 | for(int i=1;i<=n;i++) 45 | { 46 | if(!vis[i]) 47 | { 48 | cout << "Disconnected Graph" << endl; 49 | return 0; 50 | } 51 | } 52 | cout << "Connected Graph" << endl; 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Chapter 12: Graph Traversal/graphtraversal_bipartitecheck.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 12: Graph Traversal 3 | Topic: Depth First Search 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | // Adjacency list , lets suppose nodes are less then 1000 9 | vector adj[1000]; 10 | vector vis(1000, 0); 11 | vector cols(1000, 0); 12 | int flg=0; 13 | 14 | void dfs(int x, int col) 15 | { 16 | if(vis[x]) return; 17 | vis[x] = 1; 18 | cols[x] = col; 19 | int ncol=1; 20 | if(col == 1) ncol = 2; 21 | // Process node x here before going to its children 22 | for(int i=0;i> n; 37 | int edges; 38 | cin >> edges; 39 | for(int i=0;i> x >> y; 43 | adj[x].push_back(y); 44 | adj[y].push_back(x); 45 | } 46 | dfs(1,1); 47 | if(flg==1) 48 | { 49 | cout << "Not bipartite" << endl; 50 | } 51 | else cout << "Bipartite" << endl; 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Chapter 12: Graph Traversal/graphtraversal_dfs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 12: Graph Traversal 3 | Topic: Depth First Search 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | // Adjacency list , lets suppose nodes are less then 1000 9 | vector adj[1000]; 10 | vector vis(1000, 0); 11 | 12 | void dfs(int x) 13 | { 14 | if(vis[x]) return; 15 | vis[x] = 1; 16 | // Process node x here before going to its children 17 | for(int i=0;i> n; 31 | int edges; 32 | cin >> edges; 33 | for(int i=0;i> x >> y; 37 | adj[x].push_back(y); 38 | adj[y].push_back(x); 39 | } 40 | dfs(1); 41 | for(int i=1;i<=n;i++) 42 | { 43 | if(!vis[i]) 44 | { 45 | cout << "Disconnected Graph" << endl; 46 | return 0; 47 | } 48 | } 49 | cout << "Connected Graph" << endl; 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Chapter 13: Shortest Paths/shortestpaths_bellman.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 13: Shortest Paths 3 | Bellman Ford Algorithm 4 | */ 5 | #include 6 | using namespace std; 7 | int n,m; 8 | struct edge 9 | { 10 | int a; 11 | int b; 12 | int w; 13 | edge(int x,int y,int z) 14 | { 15 | a=x; 16 | b=y; 17 | w=z; 18 | } 19 | }; 20 | vector edges; 21 | int dis[10000]; 22 | 23 | void bellmanford(int source, int target) 24 | { 25 | dis[source] = 0; 26 | for(int i=0;i> n >> m; 41 | for(int i=0;i> a >> b >> w; 45 | edge x(a,b,w); 46 | edges.push_back(x); 47 | } 48 | int x,y; 49 | cin >> x >> y; 50 | bellmanford(x,y); 51 | cout << dis[y] << " "; 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Chapter 13: Shortest Paths/shortestpaths_bellman_pathretrieval.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 13: Shortest Paths 3 | Bellman Ford Algorithm 4 | */ 5 | #include 6 | using namespace std; 7 | int n,m; 8 | struct edge 9 | { 10 | int a; 11 | int b; 12 | int w; 13 | edge(int x,int y,int z) 14 | { 15 | a=x; 16 | b=y; 17 | w=z; 18 | } 19 | }; 20 | vector edges; 21 | int dis[10000]; 22 | int path[10000]; 23 | 24 | void bellmanford(int source, int target) 25 | { 26 | dis[source] = 0; 27 | for(int i=0;i> n >> m; 44 | for(int i=0;i> a >> b >> w; 48 | edge x(a,b,w); 49 | edges.push_back(x); 50 | } 51 | int x,y; 52 | cin >> x >> y; 53 | bellmanford(x,y); 54 | /* Retrieving the path */ 55 | int i = y; 56 | while(i != x) 57 | { 58 | cout << i << " "; 59 | i = path[i]; 60 | } 61 | cout << x << " "; 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /Chapter 13: Shortest Paths/shortestpaths_dijkstra.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 13: Shortest Paths Algorithm 3 | Topic: Dijsktra's Algorithm 4 | Implementation: O(nlog(n)) 5 | */ 6 | #include 7 | using namespace std; 8 | vector> adj[100000]; 9 | int dis[100000]; 10 | bool vis[100000]; 11 | 12 | void dijsktra(int source) 13 | { 14 | queue> q; 15 | dis[source] = 0; 16 | q.push({dis[source], source}); 17 | while(!q.empty()) 18 | { 19 | // Pop least distance element from the queue 20 | pair p = q.front(); 21 | q.pop(); 22 | // If it is always processed then continue; 23 | if(vis[p.second]) continue; 24 | // Mark it processed that means now it have minimum possible distance 25 | vis[p.second] = true; 26 | int d=p.first; 27 | int y=p.second; 28 | // Start pushing the neighbours into the queue 29 | for(int i=0;i d + adj[y][i].second) 33 | { 34 | dis[adj[y][i].first] = d + adj[y][i].second; 35 | q.push({dis[adj[y][i].first], adj[y][i].first}); 36 | } 37 | } 38 | } 39 | } 40 | 41 | int main() { 42 | /* 43 | Initialise all the variables 44 | */ 45 | for(int i=0;i<10000;i++) 46 | { 47 | dis[i] = INT_MAX; 48 | vis[i] = false; 49 | } 50 | int n,m; 51 | cin >> n >> m; 52 | for(int i=0;i> x >>y >> w; 56 | adj[x].push_back({y,w}); 57 | adj[y].push_back({x,w}); 58 | } 59 | int source,dest; 60 | cin >> source >> dest; 61 | dijsktra(source); 62 | cout << dis[dest] << endl; 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /Chapter 13: Shortest Paths/shortestpaths_dijkstra_paths.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 13: Shortest Paths Algorithm 3 | Topic: Dijsktra's Algorithm 4 | Implementation: O(nlog(n)) 5 | */ 6 | #include 7 | using namespace std; 8 | vector> adj[100010]; 9 | long long dis[100010]; 10 | bool vis[100010]; 11 | long long path[100010]; 12 | 13 | void dijsktra(int source) 14 | { 15 | priority_queue, vector>, greater>> q; 16 | dis[source] = (long long)0; 17 | q.push({dis[source], source}); 18 | while(!q.empty()) 19 | { 20 | // Pop least distance element from the queue 21 | pair p = q.top(); 22 | q.pop(); 23 | // If it is always processed then continue; 24 | if(vis[p.second]) continue; 25 | // Mark it processed that means now it have minimum possible distance 26 | vis[p.second] = true; 27 | int d=p.first; 28 | int y=p.second; 29 | // Start pushing the neighbours into the queue 30 | for(int i=0;i d + adj[y][i].second) 34 | { 35 | dis[adj[y][i].first] = (long long) (d + adj[y][i].second); 36 | q.push({dis[adj[y][i].first], adj[y][i].first}); 37 | path[adj[y][i].first] = y; 38 | } 39 | } 40 | } 41 | } 42 | 43 | int main() { 44 | /* 45 | Initialise all the variables 46 | */ 47 | for(int i=0;i<100010;i++) 48 | { 49 | dis[i] = INT_MAX; 50 | vis[i] = false; 51 | } 52 | int n,m; 53 | cin >> n >> m; 54 | for(int i=0;i> x >>y >> w; 58 | adj[x].push_back({y,w}); 59 | adj[y].push_back({x,w}); 60 | } 61 | dijsktra(1); 62 | if(dis[n] >= INT_MAX || vis[n] != true) 63 | { 64 | cout << -1 << endl; 65 | return 0; 66 | } 67 | vector ans; 68 | int i = n; 69 | while(i != 1) 70 | { 71 | ans.push_back(i); 72 | i = path[i]; 73 | 74 | } 75 | ans.push_back(1); 76 | for(int i=ans.size()-1;i>=0;i--) 77 | { 78 | cout << ans[i] << " "; 79 | } 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /Chapter 13: Shortest Paths/shortestpaths_floydwarshall.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 13: Shortest Paths 3 | Topic: Floyd Warshalls' Algorithm 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | int adj[1000][1000]; 9 | int dis[1000][1000]; 10 | 11 | int main() { 12 | for(int i=0;i<1000;i++) 13 | for(int j=0;j<1000;j++) 14 | { 15 | adj[i][j] = 1000000; 16 | dis[i][j] = 1000000; 17 | if(i==j) 18 | { 19 | adj[i][j]=0; 20 | dis[i][j]=0; 21 | } 22 | 23 | } 24 | int n,m; 25 | cin >> n >> m; 26 | for(int i=0;i> x >> y >> w; 30 | adj[x][y] = w; 31 | dis[x][y] = w; 32 | adj[y][x] = w; 33 | dis[y][x] = w; 34 | } 35 | 36 | for(int i=1;i<=n;i++) 37 | { 38 | for(int j=1;j<=n;j++) 39 | { 40 | for(int k=1;k<=n;k++) 41 | { 42 | dis[j][k] = min(dis[j][k],dis[j][i]+dis[i][k]); 43 | } 44 | } 45 | } 46 | for(int i=1;i<=n;i++) 47 | { 48 | for(int j=1;j<=n;j++) 49 | { 50 | cout << dis[i][j] << " "; 51 | } 52 | cout << endl; 53 | } 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Chapter 14: Tree Algorithms/treetraversal_dfs.cpp: -------------------------------------------------------------------------------- 1 | void dfs(int x,int p) 2 | { 3 | for(int i=0;i<=adj[x].size()-1;i++) 4 | { 5 | int y = adj[x][i]; 6 | if(p==y) continue; 7 | dfs(y,x); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chapter 14: Tree Algorithms/treetraversal_diameter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 14: Tree Algorithms 3 | Topic: Dp on trees 4 | Question: find the diameter of a tree 5 | Note: Here i am counting the nodes so nodes = edges+1 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | vector adj[10000]; 11 | int subtree[10000]; 12 | int diasubtree[10000]; 13 | int diameter=0; 14 | void dfs(int x, int p) 15 | { 16 | int m1,m2; 17 | m1=m2=0; 18 | for(int i=0;i m1) { m2=m1; m1=subtree[y]; } 25 | else if(subtree[y] > m2) { m2 = subtree[y]; } 26 | } 27 | diasubtree[x] = max(m1+m2+1,diasubtree[x]); 28 | diameter=max(diameter,diasubtree[x]); 29 | } 30 | 31 | int main() 32 | { 33 | for(int i=0;i<10000;i++) subtree[i]=1; 34 | int n; 35 | cin >> n; 36 | for(int i=0;i> x >> y; 40 | adj[x].push_back(y); 41 | adj[y].push_back(x); 42 | } 43 | dfs(1,-1); 44 | cout << diameter-1 << endl; 45 | } 46 | -------------------------------------------------------------------------------- /Chapter 14: Tree Algorithms/treetraversal_subtreecardinality.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 13: Tree Algorithm 3 | Topic: Tree Traversal 4 | Question : Count number of nods in subtree of each and every node. 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | vector adj[100000]; 10 | int child[100000]; 11 | 12 | void dfs(int x,int p) 13 | { 14 | for(int i=0;i> n; 27 | for(int i=0;i> x >> y; 31 | adj[x].push_back(y); 32 | adj[y].push_back(x); 33 | } 34 | dfs(1,-1); 35 | for(int i=1;i<=n;i++) 36 | { 37 | cout << i << " has " << child[i] << " number of nodes in its subtree" << endl; 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /Chapter 15: Spanning Trees/spanningtree_kruskals.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 15: Spanning Trees 3 | Topic: Kruskals Algorithm using Union Find 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int nodes = 0; 10 | int edges; 11 | 12 | int leader[10000]; 13 | 14 | // Basic structure and comparator for sorting 15 | 16 | struct edge 17 | { 18 | int from; 19 | int to; 20 | int weight; 21 | }; 22 | 23 | edge e[10000]; 24 | 25 | bool comp(edge a, edge b) 26 | { 27 | return a.weight < b.weight; 28 | } 29 | 30 | // Dijoiunt Set Union datastructure 31 | 32 | void initialise(int n) 33 | { 34 | for(int i=1;i<=n;i++) 35 | leader[i] = i; 36 | } 37 | 38 | int fset(int x) 39 | { 40 | if(leader[x] == x) return x; 41 | leader[x] = fset(leader[x]); 42 | return leader[x]; 43 | } 44 | 45 | void join(int x, int y) 46 | { 47 | x = fset(x); 48 | y = fset(y); 49 | leader[x] = y; 50 | } 51 | 52 | // Kruskals algorithm 53 | 54 | void kruskals() 55 | { 56 | vector ans; 57 | for(int i =0;i> nodes >> edges; 77 | for(int i=0;i> x >> y >> w; 81 | e[i].from = x; 82 | e[i].to = y; 83 | e[i].weight = w; 84 | } 85 | initialise(nodes); 86 | sort(e,e+edges,comp); 87 | kruskals(); 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /Chapter 15: Spanning Trees/spanningtree_prims.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 15: Spanning Trees 3 | Topic: Prims Algorithm 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int nodes = 0; 10 | int m; 11 | 12 | vector> adj[100000]; 13 | bool vis[100000] = {false}; 14 | 15 | 16 | // primes algorithm 17 | void prims() 18 | { 19 | // Make a priority Queue 20 | // Push any random node (generally 1) into the pq with w = 0 21 | // Then pop it and push all the neighbours into pq as {w, node} 22 | // If it already exist in tree don't add it else, add it and push its neighbours into the pq 23 | priority_queue,vector>,greater>> pq; 24 | pq.push({0,1}); 25 | int sum = 0; 26 | while(!pq.empty()) 27 | { 28 | pair node = pq.top(); 29 | pq.pop(); 30 | int x = node.second; 31 | int w = node.first; 32 | if(vis[x]) continue; 33 | vis[x] = true; 34 | sum+=w; 35 | for(int i =0;i> nodes >> m; 46 | for(int i =0;i < m;i++) 47 | { 48 | int x,y,z; 49 | cin >> x >> y >> z; 50 | adj[x].push_back({y,z}); 51 | adj[y].push_back({x,z}); 52 | } 53 | prims(); 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Chapter 15: Spanning Trees/spanningtree_unionfind1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 15: Spanning trees 3 | Topic: Union find datastructure 4 | Question: Implement basic union find datastructure O(n) complexity. 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // We can have atmost 1000000 independing set 11 | int leader[1000000]; 12 | 13 | // Find the leader of this set. Leader is the one who is leader of its own set. 14 | int findleader(int a) 15 | { 16 | if(leader[a] == a) 17 | return a; 18 | return findleader(leader[a]); 19 | } 20 | 21 | //Combine the leader of set b and set its leader as that of a 22 | void combine(int a,int b) 23 | { 24 | leader[findleader(b)] = findleader(a); 25 | } 26 | 27 | int main() 28 | { 29 | // We have n sets initially 30 | int n; 31 | cin >> n; 32 | // Initialise every leader as i 33 | for(int i=1;i<=n;i++) 34 | leader[i] = i; 35 | // We will take q queries to combine the sets. This is just for explaining. 36 | int q; 37 | cin >> q; 38 | for(int i = 0;i < q;i++) 39 | { 40 | int x,y; 41 | cin >> x >> y; 42 | combine(x,y); 43 | } 44 | for(int i =1;i<=n;i++) 45 | { 46 | cout << "Set of " << i << " is: " << leader[i] << endl; 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Chapter 16: Directed Graphs/directedgraphs_countingpaths.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 15: Spanning Trees 3 | Topic: Counting Paths 4 | Use DFS like we did in Topological Sorting. Before travelling to next node, using its successor, set paths(child) += paths(successor); 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | int nodes,edges; 11 | vector adj[100000]; 12 | vector ans; 13 | int vis[1000000] = {0}; 14 | int paths[1000000] = {0}; 15 | int flg=0; 16 | 17 | // count the number of paths 18 | void fpaths(int x) 19 | { 20 | if(vis[x] == 1) 21 | { 22 | flg=1; 23 | return; 24 | } 25 | vis[x] = 1; 26 | for(int i = 0;i> nodes >> edges; 39 | for(int i = 0;i < edges;i++) 40 | { 41 | int x,y; 42 | cin >> x >> y; 43 | adj[x].push_back(y); 44 | } 45 | int source; 46 | cin >> source; 47 | paths[source] = 1; 48 | fpaths(source); 49 | reverse(ans.begin(), ans.end()); 50 | for(int i = 0 ;i < ans.size(); i++) 51 | { 52 | int y = ans[i]; 53 | for(int j = 0; j 8 | using namespace std; 9 | 10 | int nodes,edges; 11 | vector adj[100000]; 12 | vector ans; 13 | int vis[1000000] = {0}; 14 | int flg=0; 15 | 16 | // Topological sorting using dfs 17 | void topologicalsort(int x) 18 | { 19 | if(vis[x] == 1) 20 | { 21 | flg=1; 22 | return; 23 | } 24 | vis[x] = 1; 25 | for(int i = 0; i < adj[x].size(); i++) 26 | { 27 | int y = adj[x][i]; 28 | if(vis[y] == 2) continue; 29 | topologicalsort(y); 30 | } 31 | vis[x] = 2; 32 | ans.push_back(x); 33 | } 34 | 35 | int main() 36 | { 37 | cin >> nodes >> edges; 38 | for(int i = 0;i < edges;i++) 39 | { 40 | int x,y; 41 | cin >> x >> y; 42 | adj[x].push_back(y); 43 | } 44 | for(int i = 1; i < nodes;i++) 45 | { 46 | if(vis[i]) continue; 47 | topologicalsort(i); 48 | } 49 | if(flg) 50 | { 51 | cout << "Topological sort is not possible" << endl; 52 | return 0; 53 | } 54 | for(int i = ans.size()-1; i >= 0 ;i--) 55 | { 56 | cout << ans[i] << " "; 57 | } 58 | cout << endl; 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Chapter 17: Strong Connectivity/strongconnectivity_kosaraju.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 17: Strong connectivity 3 | Topic: Kosarau Algorithm 4 | Given a directed graph, number the nodes on the basis of the component to which they belong 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | int n,e; // Number of edges and nodes 11 | int compo[100000] = {0}; // All nodes in componenet 0 will have this value as 0 12 | vector adj[100000]; // The adjacency list of the graph 13 | vector revadj[100000]; // Adjacency list of reverse edged graph 14 | vector sequence; // Sequence of DFS 1 15 | bool vis[100000]= {false}; // Visted flags 16 | int curr=0; // Value of current compoenent being searched 17 | 18 | 19 | // DFS 1 : Finds the order in which the nodes will be searched next 20 | void dfs(int x) 21 | { 22 | if(vis[x]) return; 23 | vis[x]=1; 24 | for(int i=0;i=0;i--) 61 | { 62 | int y = sequence[i]; 63 | if(vis[y]) continue; 64 | dfs2(y); 65 | curr++; 66 | } 67 | 68 | for(int i=1;i<=n;i++) 69 | { 70 | cout << compo[i] << " "; 71 | } 72 | cout << endl; 73 | } 74 | 75 | int main() 76 | { 77 | 78 | cin >> n >> e; 79 | for(int i =0;i> x >> y; 83 | adj[x].push_back(y); 84 | revadj[y].push_back(x); 85 | } 86 | kosaraju(); 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /Chapter 18: Tree Queries/treequeries_distancebetween2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 17: Tree Queries 3 | Topic: Distance between two nodes 4 | Method : 5 | Height of x + height of y - height of lca(x,y) 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | vector adj[100000]; 12 | vector euler; 13 | int vis[100000] = {0}; 14 | int height[100000] = {0}; 15 | int h2[100000] = {0}; 16 | 17 | void dfs(int x,int h) 18 | { 19 | if(vis[x]) return; 20 | vis[x]=1; 21 | h2[x] = h; 22 | euler.push_back(x); 23 | height[euler.size()-1] = h; 24 | for(int i=0;i> n >> q; 41 | for(int i=0;i> x >> y; 45 | adj[x].push_back(y); 46 | adj[y].push_back(x); 47 | } 48 | dfs(1,0); 49 | while(q--) 50 | { 51 | int x,y; 52 | cin >> x >> y; 53 | int f,s; 54 | for(int i=0;is) 71 | { 72 | swap(f,s); 73 | } 74 | int mh=INT_MAX; 75 | int mhi=0; 76 | for(int i=f;i<=s;i++) 77 | { 78 | if(height[i] < mh) 79 | { 80 | mh = height[i]; 81 | mhi = i; 82 | } 83 | } 84 | cout << h2[x]+h2[y]-2*mh << endl; 85 | } 86 | return 0; 87 | } 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /Chapter 18: Tree Queries/treequeries_findingancestor_sparsetable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 17: Tree Queries 3 | Topic: Finding Ancestors 4 | Given a tree and 2 values x and k. Find kth ancestor of x above x. 5 | Using sparse table 6 | O(nlogn) - table formation 7 | O(logn) - Per query 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | int n,q; 14 | 15 | vector adj[100000]; 16 | int sparse[100000][10]; 17 | int vis[100000] = {0}; 18 | 19 | // Sparse[x][0] stores the parent of node x only. 20 | // Further sparse[x][1] = sparse[sparse[x][0]][0] 21 | void dfs(int x) 22 | { 23 | if(vis[x]) return; 24 | vis[x]=1; 25 | for(int i=0;i> n >> q; 50 | for(int i=0;i> x >> y; 54 | adj[x].push_back(y); 55 | adj[y].push_back(x); 56 | } 57 | dfs(1); 58 | makesparse(0); 59 | while(q--) 60 | { 61 | int x,k; 62 | cin >> x >> k; 63 | int y=0; 64 | // Using sparse table to query the kth ancstor. k can be written as 1011 (k = 11) 65 | // Now, 11 = 8 + 2 + 1 = 2^3 + 2^1 + 2^0 , hence we start from max possible power 66 | // And then keep on increasing y till y=k 67 | for(int i=10;i>=0;i--) 68 | { 69 | int rnge = pow(2,i); 70 | if(y+rnge <= k) 71 | { 72 | x = sparse[x][i]; 73 | y=y+rnge; 74 | } 75 | } 76 | cout << x << endl; 77 | } 78 | return 0; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /Chapter 18: Tree Queries/treequeries_findingancestors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 17: Tree Queries 3 | Topic: Finding Ancestors 4 | Given a tree and 2 values x and k. Find kth ancestor of x above x. 5 | Going with brute force. 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | vector adj[100000]; 12 | int parent[100000]; 13 | int vis[100000] = {0}; 14 | 15 | void dfs(int x) 16 | { 17 | if(vis[x]) return; 18 | vis[x]=1; 19 | for(int i=0;i> n >> q; 32 | for(int i=0;i> x >> y; 36 | adj[x].push_back(y); 37 | adj[y].push_back(x); 38 | } 39 | dfs(1); 40 | while(q--) 41 | { 42 | int x,k; 43 | cin >> x >> k; 44 | int nf=0; 45 | while(k) 46 | { 47 | if(parent[x]==0) 48 | { 49 | nf=1; 50 | break; 51 | } 52 | x = parent[x]; 53 | k--; 54 | } 55 | if(nf) 56 | { 57 | cout << "Not Found" << endl; 58 | } 59 | else 60 | { 61 | cout << "Found:" << x << endl; 62 | } 63 | } 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Chapter 18: Tree Queries/treequeries_findingrangesum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 17: Tree Queries 3 | Topic: Subtree Queries 4 | Given a tree rooted at 1. You have to answer q queries. Queries can be of two types 5 | 1. Update the node value. 6 | 2. Find the subtree sum. 7 | Update takes place in O(1) and Every query is answered in O(n). 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | // adj stores the tree 14 | // val stores the values of ith node and can be referenced using val[i] 15 | // size stores the size of subtree of any ith node and can be referenced using size[i] 16 | int n,q; 17 | vector adj[100000]; 18 | int aval[100000] = {0}; 19 | int val[100000] = {0}; 20 | int size[100000] = {0}; 21 | int nodeid[100000] = {0}; 22 | int vis[100000]; 23 | int id=1; 24 | int dfs(int x) 25 | { 26 | if(vis[x]) return 0; 27 | int cid = id; 28 | nodeid[id++] = x; 29 | vis[x] = 1; 30 | size[cid]=1; 31 | for(int i=0;i> n >> q; 69 | for(int i=0;i> x >> y; 73 | adj[x].push_back(y); 74 | adj[y].push_back(x); 75 | } 76 | for(int i=1;i<=n;i++) 77 | { 78 | int x; 79 | cin >> x; 80 | aval[i]=x; 81 | } 82 | dfs(1); 83 | // Uncomment below to see the nodeid , size and node values. 84 | // printinfo(); 85 | 86 | while(q--) 87 | { 88 | int choice; 89 | cin >> choice; 90 | if(choice == 1) 91 | { 92 | int x,v; 93 | cin >> x >> v; 94 | for(int i=1;i<=n;i++) 95 | { 96 | if(nodeid[i] ==x) 97 | val[x]=v; 98 | } 99 | } 100 | else 101 | { 102 | int x; 103 | cin >> x; 104 | int s=0; 105 | int st=0; 106 | int ans=0; 107 | for(int i=1;i<=n;i++) 108 | { 109 | if(nodeid[i] ==x) 110 | { 111 | st=i; 112 | s=size[i]; 113 | break; 114 | } 115 | } 116 | for(int i=0;i 11 | using namespace std; 12 | 13 | vector adj[100000]; 14 | int height[100000] = {0}; 15 | int parent[100000] = {0}; 16 | bool vis[100000] = {0}; 17 | 18 | void dfs(int x,int h) 19 | { 20 | if(vis[x]) return; 21 | vis[x]=1; 22 | height[x] = h; 23 | for(int i=0;i> n; 36 | for(int i=0;i> x >> y; 40 | adj[x].push_back(y); 41 | adj[y].push_back(x); 42 | } 43 | dfs(1,1); 44 | int x,y; 45 | cin >> x >> y; 46 | if(height[x] > height[y]) swap(x,y); 47 | while(height[y] > height[x]) 48 | { 49 | y = parent[y]; 50 | } 51 | while(x!=y) 52 | { 53 | x=parent[x]; 54 | y=parent[y]; 55 | } 56 | cout << x << endl; 57 | return 0; 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Chapter 18: Tree Queries/treequeries_lca_method2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 17: Tree Queries 3 | Topic: Lowest Common Ancestor 4 | Method 2: 5 | Idea: During a tree traversal a given node is visited number of time that is equal to the number of its children. The same node is also the LCA when two of its children are the query nodes. Now, this node will be visited atleast once, might be more but atleast once between these two node findings. Thus we will make a traversal array and find this LCA between them. Now LCA is between but which ? LCA is the one with least height. How? Try and see :P. 6 | 7 | This code does not have any seg tree or sparse table implementation. These Datastructure can reduce the query complexity to O(log(n)) 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | vector adj[100000]; 14 | vector euler; 15 | int vis[100000] = {0}; 16 | int height[100000] = {0}; 17 | 18 | void dfs(int x,int h) 19 | { 20 | if(vis[x]) return; 21 | vis[x]=1; 22 | euler.push_back(x); 23 | height[euler.size()-1] = h; 24 | for(int i=0;i> n >> q; 40 | for(int i=0;i> x >> y; 44 | adj[x].push_back(y); 45 | adj[y].push_back(x); 46 | } 47 | dfs(1,1); 48 | while(q--) 49 | { 50 | int x,y; 51 | cin >> x >> y; 52 | int f,s; 53 | for(int i=0;i 8 | using namespace std; 9 | 10 | bool checkprime(int x) 11 | { 12 | for(int i=2;i*i<=x;i++) 13 | { 14 | if(x%i == 0) return false; 15 | } 16 | return true; 17 | } 18 | int main() 19 | { 20 | int x; 21 | cin >> x; 22 | if(checkprime(x)) 23 | { 24 | cout << "Prime" << endl; 25 | } 26 | else cout << "Not Prime" << endl; 27 | return 0; 28 | } 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Chapter 21: Number Theory/Prime Numbers/primefactor_sieveoferatosthenes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 21: Number Thory 3 | Topic: Sieve of Eratosthenes 4 | Used to find all the prime numbers from 1 to n in O(nloglogn) 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | bool sieve[100000] = {true}; 11 | 12 | void sieves(int n) 13 | { 14 | sieve[0] = sieve[1] = false; 15 | for(int i=2;i<=n;i++) 16 | { 17 | if(!sieve[i]) continue; 18 | for(int j=i+i;j<=n;j+=i) 19 | { 20 | sieve[j]=false; 21 | } 22 | } 23 | } 24 | int main() 25 | { 26 | for(int i=0;i<100000;i++) sieve[i]=true; 27 | int n; 28 | cin >> n; 29 | sieves(n); 30 | for(int i=2;i<=n;i++) 31 | { 32 | if(sieve[i]) 33 | { 34 | cout << i << " "; 35 | } 36 | } 37 | return 0; 38 | } 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Chapter 21: Number Theory/gcd_euclidsalgorithm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chapter 21: Number Thory 3 | Topic: Euclids algorithm for finding GCD 4 | gcd(a,b) = a if b==0 5 | else if it gcd(b,a%b) 6 | 7 | Why ? 8 | Let a > b , then 9 | 10 | a = b.q + r 11 | now gcd(b.q + r, b) 12 | = gcd(r, b) 13 | */ 14 | 15 | #include 16 | using namespace std; 17 | 18 | int gcd(int x,int y) 19 | { 20 | if(x==0) return y; 21 | if(y==0) return x; 22 | return gcd(y, x%y); 23 | } 24 | int main() 25 | { 26 | int x,y; 27 | cin >> x >> y; 28 | cout << gcd(max(x,y),min(x,y)); 29 | return 0; 30 | } 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Pulkit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Handbook Codes 2 |
3 |

4 | 5 | 6 | 7 |

Handbook Codes

8 | 9 |

10 | A C++ codes repository for Competitive Programming Handbook by Antti Laaksonen. 11 |
12 | Report Bug 13 | · 14 | Request Code 15 |

16 |

17 | 18 | 19 | 20 | 21 |
22 | Table of Contents 23 |
    24 |
  1. 25 | About The Project 26 |
  2. 27 |
  3. Usage
  4. 28 |
  5. Roadmap
  6. 29 |
  7. Contributing
  8. 30 |
31 |
32 | 33 | 34 | 35 | 36 | ## About The Project 37 | 38 | A Competitive Programmers Handbook by Antti Laaksonen is one of the good books which touches each topic for competitive programming. But the problem is that it just touches those topics and it becomes hard for a beginner to grasp those concepts and implement them simultaneously. I guess the book expects the reader to have at least once been introduced to the concepts. This repository comprises of all the possible codes from the same. 39 | [Link](https://github.com/pllk/cphb) 40 | 41 | ## Usage 42 | 43 | Read the book. Unable to understand any part? Come here look at the code. 44 | 45 | 46 | 47 | ## Roadmap 48 | 49 | - [Open issue](https://github.com/pulkit1joshi/handbook_codes/issues) if you want a particular part of the handbook to be implemented earlier or have any issue in the present codes. 50 | - Further, more codes will be added as I get time. :) 51 | 52 | 53 | 54 | 55 | ## Contributing 56 | 57 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 58 | 59 | 1. Fork the Project 60 | 2. Create your Feature Branch (`git checkout -b newalgorithm`) 61 | 3. Commit your Changes (`git commit -m 'Added algorithm/code: "Description" , Part of book: "Description"'`) 62 | 4. Push to the Branch (`git push origin newalgorithm`) 63 | 5. Open a Pull Request 64 | 65 | --------------------------------------------------------------------------------