[
  {
    "path": ".gitignore",
    "content": ".vscode/*"
  },
  {
    "path": "Adhoc + Basic/Reservoir_sampling.cpp",
    "content": "/**\n * Question: Is there a way to get random number from a stream of integers?\n * Yes. We create a reserviour of size 1 (single element).\n * We iterate over the stream and for each element we have a probability of 1/i to replace the element in the reserviour.\n * This is because the probability of not replacing the element is (i-1)/i and the probability of replacing the element is 1/i.\n * So the probability of not replacing the element after i iterations is (i-1)/i * (i-2)/i-1 * ... * 1/2 = 1/i.\n *\n * Ref: https://www.youtube.com/watch?v=A1iwzSew5QY\n * Que: https://leetcode.com/problems/linked-list-random-node/\n */\n\n#include <bits/stdc++.h>\n\nusing namespace std;\n\nint findRandom(vector<int> arr)\n{\n    int reservoir, len = 0;\n\n    reservoir = arr[0];\n    len = 1;\n\n    while (len < arr.size())\n    {\n        // probability of replacing charachter in reservoir is 1/len\n        // Assuming rand() produces int upto infinity\n        if (rand() % len == 0)\n        {\n            reservoir = arr[len];\n        }\n        len++;\n    }\n\n    return reservoir;\n}\n\n// getting random index based on weight in a stream on weights\n// print randomNum when 0 comes in stream\nint weightedRandomIndex(const std::vector<int>& weights) {\n    double totalWeight = 0;\n    int selectedIndex = -1;\n\n    for (int i = 0; i < weights.size(); ++i) {\n        if (weights[i] == 0) cout << selectedIndex;\n\n        totalWeight += weights[i];\n        if (((double)rand()) / RAND_MAX * totalWeight < weights[i]) {\n            selectedIndex = i;\n        }\n    }\n    return selectedIndex;\n}\n\nint main()\n{\n    vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\n    cout << \"Radom num from inf list is \" << findRandom(arr);\n}\n"
  },
  {
    "path": "Adhoc + Basic/Sieve_of_Eratosthenes.cpp",
    "content": "/*Questions solved\n\tprecomputation\t\t\t\t\t-> \tO(N(lnlnN))\n1.\tis n a prime\t\t\t\t\t->\tO(1)\n2.\tfactors of some F\t\t\t\t->\tO(ln NF)\n3.\tprimes between a range\t\t\t->\tO(range)\n4.\tsmallest prime greater than k\t->\tO(ln k)\n*/\n\n#include<bits/stdc++.h>\n\nusing namespace std;\n#define LIM 10000\n\nbool isComposite[LIM];\nint factor[LIM];\t//stores one of the factor of the indx, we can find other factor easily\nvector<int> primes;\t//stores list of primes in LIM\n\nint main() \n{\n\tint i;\n\t//PreComputation\n\tisComposite[1]=true; //assume for simplicity as 1 is NOT PRIME.\n\tfor(int i=2;i<sqrt(LIM);i++)\n\t{\n\t\tif(isComposite[i])\tcontinue;\n\t\tfor(int j=2*i; j<LIM; j += i)\t//move by i steps at once\n\t\t{\n\t\t\tisComposite[j]=true;\n\n\t\t\tif(factor[j] == 0)\tfactor[j]=i;\t\n\t\t}\n\t}\n\n\tfor(i=3;i<LIM;i+=2)\n\t{\n\t\tif(!isComposite[i])\tprimes.push_back(i);\n\t}\n\n\n\t//Q1\n\tint n;\n\tcout<<\"Enter number you want to check to be prime:\";\n\tcin>>n;\n\tcout<<!isComposite[n]<<endl;\n\t\n\t//Q2\n\tint F;\n\tcout<<\"Enter Number you want to factorize: \";\n\tcin>>F;\n\n\twhile (isComposite[F] and F!=1)\n\t{\n\t\tcout<<factor[F]<<\" \";\t//F = a * b  if a is a prime which is stored.\n\t\tF=F/factor[F];\n\t}\n\tcout<<F<<endl;\t//final prime number.\n\n\t//Q3\n\tint a,b;\n\tcout<<\"Enter range you want to check: \";\n\tcin>>a>>b;\n\tauto itr = upper_bound(primes.begin(),primes.end(),a);\n\tfor( ; *itr <= b and itr!=primes.end() ; itr++ )\n\t{\n\t\tcout<<*itr<<\" \";\n\t}\n\n\t//Q4\n\tint k;\n\tcin>>k;\n\tcout<<\"Enter number to get just greater prime:\";\n\tcin>>k;\n\titr = upper_bound(primes.begin(),primes.end(),k);\n\tif(itr!=primes.end())\n\tcout<<*itr;\n\n\n\t\n}\n\n\n\n\n"
  },
  {
    "path": "Adhoc + Basic/Two_Pointer.cpp",
    "content": "// Dutch National Flag Problem\n// Sot 0,1,2 with a single traversal\n\n/*\n* Must satisfy condn\n* [start,lo]  = 0\n* [hi+1,end]  = 2\n* [mid, hi-1] = Don't know\n*/\n// Array has 0,1,2 as elements sort the array:\nvoid sortColors(vector<int>& arr) {\n    int lo=0,mid=0,hi=arr.size()-1;\n    //\n    while(mid <= hi) {\n        if(arr[mid] == 0)\n            swap(arr[lo++],arr[mid]);\n        else if(arr[mid] == 1)\n            mid++;\n        else // arr[mid] = 2\n            swap(arr[hi--],arr[mid]);\n    }\n}\n"
  },
  {
    "path": "Adhoc + Basic/binary_search_I.cpp",
    "content": "// Question link -> https://community.topcoder.com/stat?c=problem_statement&pm=1901&rd=4650\n// Artical link -> https://www.topcoder.com/community/competitive-programming/tutorials/binary-search\n// Ref link -> https://www.youtube.com/watch?v=GU7DpgHINWQ\n// Ref link -> https://leetcode.com/discuss/interview-question/1322500/5-variations-of-Binary-search-(A-Self-Note)/?fbclid=IwAR1tgOv9b7dNA9dyqBEHCmNdqkGrBxItE7vqBRVqL0Rk6UE65_fLO8J1JI8\n\n// Here in binary search we basically want o function that return boolean value if it is ans yes or no\n// And we want the indxe from where true begins or false begins\n#include<bits/stdc++.h>\n\nusing namespace std;\n\nint getMostWork_method1(int folders[], int workers,int n) \n{\n    // Number of workers maximum in a division can be between 1 and 10^6(Can be lower but in general)\n    int lo = 1, hi = 1e5+1;\n\n    while (lo < hi) \n    {\n        int mid = lo + (hi - lo) / 2;\n        int required = 1, sum = 0;\n\n        for (int i = 0; i < n; ++i) \n        {\n            if (sum + folders[i] <= mid) // the current worker can handle it\n                sum += folders[i];\n            else // assign nemidt worker\n            {\n                ++required;\n                sum = folders[i];\n            }\n        }\n        //               |            is the indx we want to find\n        // F F F F F F F T T T T T T \n        // if(p(mid)==true) hi = mid\n        if (required <= workers)\n            hi = mid;\n        else\n            lo = mid + 1;\n    }\n    return lo; // lo=hi so doesn't matter\n}\n\nbool ispossible(int folders[],int n, int no, int workers)\n{\n    int required = 1, sum = 0;\n    for (int i = 0; i < n; ++i) \n    {\n        if (sum + folders[i] <= no) // the current worker can handle it\n            sum += folders[i];\n        else // assign nemidt worker\n        {\n            ++required;\n            sum = folders[i];\n        }\n    }\n    if(required <= workers)\n        return true;\n    return false;\n}\n\nint getMostWork_method2(int folders[],int workers, int n)\n{\n    int hi=1e9,lo=0,mid;\n    bool check_low,check_mid,check_upp;\n\n    while(lo <= hi)\n    {\n        mid = (lo+hi)/2;\n        check_low=ispossible(folders,n,mid-1,workers);\n        check_mid=ispossible(folders,n,mid,workers);\n        check_upp=ispossible(folders,n,mid+1,workers);\n\n        if(check_low==0 && check_mid==1)\n                return mid;\n        else if(check_mid==0 && check_upp==1)\n                return mid+1;\n        else if(check_upp==1)\n                hi=mid+1;\n        else if(check_low==0)\n                lo=mid-1;\n    }\n    return 0;\n}\n\nint main()\n{\n    int arr[15] = { 568, 712, 412, 231, 241, 393, 865, 287, 128, 457, 238, 98, 980, 23, 782 };\n    int n = sizeof(arr)/sizeof(int);\n\n    // Divide the work in 4 workers such that the work done per worker is minimum\n    cout << \"Minimum possible maximum folders per person \" <<getMostWork_method1(arr,4,n) << \"\\n\";\n    cout << \"Minimum possible maximum folders per person \" <<getMostWork_method2(arr,4,n);\n}\n"
  },
  {
    "path": "Adhoc + Basic/binary_search_II.cpp",
    "content": "// Reference --> https://www.youtube.com/watch?v=U66U1-umNbQ&t=1s\n// Reference --> https://www.youtube.com/watch?v=V343UXw4P3Y\n\n// upper bound return first element which is >value. If not, return end().\n// lower bound return first element which is ≥value. If not, return end().\n\n/*\nElements are : 1 3 5 7 9 \n******* lower_bound *********\nlower bound of 5 in the set is: 5\nlower bound of 1 in the set is: 1\nlower bound of 4 in the set is: 5\n****** upper_bound ************\nupper bound of 5 in the set is: 7\nupper bound of 1 in the set is: 3\nupper bound of 4 in the set is: 5\n*/\n\n#include<bits/stdc++.h> \nusing namespace std;\n\n/*\n* Intresting observation note worthy : \n* lo+(hi-lo)/2 = (lo+hi)/2  is skewed to towards lo. (ex. (1+4)/2 = 2.5 but it return 2)\n* hi = mid can be seen a skewed towards hi so this (lo+hi)/2 works fine with hi = mid\n* Similarly\n* lo = mid is skewed towards lo so using (lo+hi)/2 A as mid will result in SEG so instead use\n* (hi-lo+1)/2 is skewed towards hi ex. 1+(4-1+1)/2 = 3.5 = 3 so we got ceil(2.5)\n* mid = lo + (hi-lo+1)/2\n*/\n\nint lower_bound_(vector<int> arr, int target){\n    int lo = 0;\n    int hi = arr.size()-1;\n\n    while(lo<hi){\n        int mid = (lo+hi)/2;\n\n        if(arr[mid] < target)\n            lo = mid+1;\n        else if(arr[mid] > target) \n            hi = mid-1;\n        // Our index needed may be this index mid or may be less than mid. \n        else\n            hi = mid;  \n    }\n    return lo;\n}\n\nint upper_bound_(vector<int> arr, int target){\n    int lo = 0;\n    int hi = arr.size()-1;\n\n    while(lo<hi){\n        int mid = lo+(hi-lo+1)/2;   // Note from observation above\n\n        if(arr[mid] < target)\n            lo = mid+1;\n        else if(arr[mid] > target)\n            hi = mid-1;\n        // Our index needed may be this index mid or may be greater than mid.\n        else\n            lo = mid;\n    }\n    return lo;\n}\n\n/*\nRotated sorted array will look something like this\nonly at pivot arr[pivot] > arr[pivot+1]\n   /\n  /  \n /          <- case 1 (mid > arr[0])\n/ \n      /    \n     /      <- case 2 (mid < arr[0])\n    /  \nex. {4, 5, 6, 7, 0, 1, 2}\n*/\nint find_pivot(vector<int> &arr) {\n\n    int lo = 0, hi = arr.size()-1;\n\n    while(lo < hi) {\n        int mid = (lo+hi)/2;\n        if(arr[mid] > arr[0]){\n            if(arr[mid] > arr[mid+1])\n                return mid;\n            else\n                lo = mid+1;\n        }\n        else{\n            if(arr[mid-1] > arr[mid])\n                return mid-1;\n            else\n                hi = mid-1;\n        }\n    }\n    return lo;\n}\n\n\nint pivotedBinarySearch(vector<int> &arr, int target){\n    // Task 1: Find the highest elements index \n    // Task 2: Simple binary search in one of the ranges\n\n    int pivot = find_pivot(arr);   \n\n    vector<int> :: iterator it;\n    if(target >= arr[0])\n        it =  lower_bound(arr.begin(),arr.begin()+pivot,target);\n    else\n        it =  lower_bound(arr.begin()+pivot+1, arr.end(),target); \n  \n    if(*it != target)\n        return -1;\n    else \n        return it-arr.begin();\n}\n\n\n\nint main(){\n    // Array is sorted then rotated task is to find index of key element.\n    vector<int> arr = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };\n    cout << \"Index of the element is : \"<< pivotedBinarySearch(arr, 2);\n\n    \n}\n"
  },
  {
    "path": "Adhoc + Basic/binary_search_III.cpp",
    "content": "#include<bits/stdc++.h>\n\nusing namespace std;\n\nint lowerBound(vector<int> arr, int target) {\n    int left = 0;\n    int right = arr.size() - 1;\n    int result = -1;\n\n    while (left <= right) {\n        int mid = left + (right-left)/2; // To help with out of bounds\n        if (arr[mid] >= target) { // we want the value in ans if the target exists\n            result = mid;\n            right = mid - 1;\n        }\n        else {\n            left = mid + 1;\n        }\n    }\n    return result;\n}\n\nint upperBound(vector<int> arr, int target) {\n    int left = 0;\n    int right = arr.size() - 1;\n    int result = -1;\n\n    while (left <= right) {\n        int mid = left + (right-left)/2; // To help with out of bounds\n        if (arr[mid] > target) { // we want a greater than target value.\n            result = mid - 1;\n            right = mid - 1;\n        }\n        else {\n            left = mid + 1;\n        }\n    }\n    return result;\n}"
  },
  {
    "path": "Arrays/MedianOfSortedArrays.cpp",
    "content": "// Problem Link : https://leetcode.com/problems/median-of-two-sorted-arrays/\n/*\n\nIf we merge two arrays in sorted manner the central values will give us the median\n\n1 4 5\n2 6 7 8 9\n\n1 2 4 5 6 7 8 9   -> (5+6)/2 \n\nThe left half and right half of this combined array has elements from both arrays\n\n1 4 5   |    INT_MAX     <-  from arr1    (INT_MAX because there was no other element to right, similarly INT_MIN if there's no element to left)\n    2   |    6 7 8 9     <-  from arr2\n\nall elements in the left half should be smaller than all elements on right in this configuration \nso basically 5<6 && 2<INT_MAx     (why not compare 2 and 6?  they are from same array so they will be already in sorted order no need to check that)\n\nIn general\n\n. . . leftx  |  rightx . . .\n. . . lefty  |  righty . . .\n\nleftx<=righty && lefty<=rightx  for valid configuration\n\nNow if we find a point in first array, we can get all others since we divide into halves (refer code)\nso find this point using binary search\n\n*/\n\n#include<bits/stdc++.h>\nusing namespace std;\n\nclass Solution {\npublic:\n    double findMedian(vector<int>&a,vector<int>&b){\n        int m=a.size();\n        int n=b.size();\n        int l=0,r=m;\n        while(l<=r){\n            int partx=l+(r-l)/2;\n            int party=(m+n+1)/2-partx;\n            int maxlx=(partx==0)?INT_MIN:a[partx-1];\n            int minrx=(partx==m)?INT_MAX:a[partx];\n            int maxly=(party==0)?INT_MIN:b[party-1];\n            int minry=(party==n)?INT_MAX:b[party];\n            if(maxlx<=minry&&maxly<=minrx){\n                if((m+n)%2==0)\n                    return (double)(max(maxlx,maxly)+min(minrx,minry))/2;\n                else\n                    return (double)(max(maxlx,maxly));\n            }else if(maxlx>minry)\n                r=partx-1;\n            else\n                l=partx+1;\n        }\n        return -1.0;\n    }\n    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {\n        if(nums1.size()<nums2.size())\n        {\n            return findMedian(nums1,nums2);\n        }  \n        else\n        {\n            return findMedian(nums2,nums1);\n        }\n    }\n};"
  },
  {
    "path": "Arrays/MedianOfStream.cpp",
    "content": "/*\n\n\tTime complexity: O(N*(log(N))) \n\tSpace complexity: O(N)\n\t\n\twhere N is the total number of elements in the array.\n\n*/\n\n#include<bits/stdc++.h>\nusing namespace std;\n\nvector<int> findMedian(vector<int> &arr, int n){\n\t\n\t// To store the medians\n\tvector<int> medians;\n\t\n\t// max heap\n\tpriority_queue<int> lo;  \n\t\n\t//min heap                            \n    priority_queue<int, vector<int>, greater<int>> hi;   \n    \n    for(int i = 0; i < n; i++){\n    \t\n    \tint num = arr[i];\n    \t\n    \t// Add to max heap\n    \tlo.push(num);                                \n\t\t\n\t\t// Balancing step, that is inserting the current element at its position that is either less than median or more than median value\n        hi.push(lo.top());                        \n        lo.pop();\n\n\t\t// Maintain size property, as 'lo' can have utmost one more element than 'hi' or both have equal number of elements\n        if (lo.size() < hi.size()) {                    \n            lo.push(hi.top());\n            hi.pop();\n        }\n        \n        int median;\n        \n        // For odd number of elements\n        if(lo.size() > hi.size()){\n        \t\n        \tmedian = lo.top();\n        \t\n\t\t}\n\t\t// For even number of elements\n\t\telse{\n\t\t\t\n\t\t\tmedian = (lo.top() + hi.top())/2;  \n\t\t\t\n\t\t}\n        \n    \tmedians.push_back(median);\n\t}\n\t\n\treturn medians;\n\n}\n\n"
  },
  {
    "path": "Arrays/MonotonicStack.cpp",
    "content": "/**\n * @file MonotonicStack.cpp\n * @author Nisarg \n * @brief A monotonic stack is a stack whose elements are monotonically increasing or descreasing.\n * Sometimes we store the index of the elements in the stack and make sure the elements corresponding to those indexes in the stack forms a mono-sequence\n * \n * @question Find next smaller/greater element for each element in O(n) Time complexity.\n * \n */\n\n\n#include<bits/stdc++.h>\nusing namespace std;\n\nvector<int> nextGreaterElement(vector<int> arr) {\n    stack<pair<int,int> > stck;\n    int i,n = arr.size();\n    vector<int> ans(n);\n    for(i=0;i<n;i++) { // Can be written as n->1 \n        if(stck.empty()) {            \n            stck.push({arr[i], i});\n            continue;\n        }\n        while(!stck.empty() && stck.top().first < arr[i])  {\n            ans[stck.top().second] = arr[i];\n            stck.pop();\n        }\n        stck.push({arr[i],i});   \n    }\n\n    while(!stck.empty()) {\n        ans[stck.top().second] = -1;\n        stck.pop();\n    }\n    return ans;\n}\n\n// Stack always array indices where values are in increasing order.\nvector<int> nextSmallerElement(vector<int> arr) {\n    stack<int> stck;\n    int i,n = arr.size();\n    vector<int> ans(n, -1);\n\n    for(i=0;i<n;i++) {\n        while(!stck.empty() and arr[i] < arr[stck.top()]) {\n            ans[stck.top()] = arr[i];\n            stck.pop();\n        }\n        stck.push(i);\n    }\n    return ans;\n}\n\nint main() {\n    vector<int> arr = {1, 7, 2, 3, 1, 8};\n\n    vector<int> nextGreater = nextGreaterElement(arr);\n    cout << \"\\nNext Greater Element: \";\n    for (auto ele: nextGreater) \n            cout << ele << \" \";\n    vector<int> nextSmaller = nextSmallerElement(arr);\n    cout << \"\\nNext Smaller Element: \";\n    for (auto ele: nextSmaller) \n            cout << ele << \" \";\n\n}"
  },
  {
    "path": "Arrays/Sliding Window Max.cpp",
    "content": "/**\n * https://leetcode.com/problems/sliding-window-maximum/solutions/5503612/best-code-in-c-must-see-easy-to-understand-beats-98-48-solution/\n\n Find max value in each range of k size.\n */\n"
  },
  {
    "path": "Arrays/TrappingRainwater.cpp",
    "content": "#include<bits/stdc++.h>\r\nusing namespace std;\r\n\r\nclass Solution {\r\npublic:\r\n    int trap(vector<int>& height) {\r\n        \r\n        int n = height.size(); \r\n        int left=0; int right=n-1;\r\n        int res=0;\r\n        int maxleft=0, maxright=0;\r\n        \r\n        while(left<=right){\r\n            \r\n            if(height[left]<=height[right]){\r\n\r\n                if(height[left]>=maxleft) maxleft=height[left];\r\n                else res+=maxleft-height[left];\r\n                left++;\r\n            }\r\n            else{\r\n\r\n                if(height[right]>=maxright) maxright= height[right];\r\n                else res+=maxright-height[right]; \r\n                right--;\r\n            }\r\n        }\r\n        return res;\r\n    }\r\n};\r\n\r\n\r\n/*\r\n\r\nwe are concerned with maximum height on left and that on right, \r\nso we can maintain two prefix and suffix arrays to precompute the max_left and max_right and the answer will be min(max_left,max_right) - curr_height\r\nBut since we are only concerned with the minimum of the left and right max we can get rid of the extra space\r\n\r\n*/"
  },
  {
    "path": "Arrays/readme.md",
    "content": "Deletion in a vector takes O(1) time if order doesn't matter.\nDelete ith indexed value.\n\n```\nswap(arr[i], arr[n-1]);\narr.pop_back();\n```\n"
  },
  {
    "path": "Bit-mask/Bitmask_Basic.cpp",
    "content": "// Reference -> https://www.youtube.com/watch?v=7FmL-WpTTJ4\n// We are using bitmask to store the numbers between 1 and 10 (in integers) [Each bit represents a subset of intergers 1 to 10]. 15 represents set with 1,2,3,4.]\n// left shifting (x<<y) is equivalent to multiplying x with 2^y \n// right shifting (x>>y) is equivalent to dividing x with 2^y. \n\n#include<bits/stdc++.h>\n\nusing namespace std;\n\n// If element is present it will get deleted and if its not there it will get added\nvoid erase_or_add(int n, int& subset)\n{\n    subset = subset ^ 1<<(n-1);\n}\nvoid display(int subset)\n{\n    cout<<\"The subset is: \";\n    // i is the ith bit from right to left \n    // 0th  bit represents 1\n    for(int i=0;i<9;i++)\n    {\n        if(1<<i&subset)\n            cout << i+1<<\" \";\n    }\n    cout<<\"\\n\";\n}\n\nint main()\n{\n    // num represents subset of numbers from 1 to 10\n    int num = 15;\n    display(num);\n    // delete the d from subset num\n    int d = 4;\n    erase_or_add(d,num);\n    display(num);\n\n    d=9;\n    erase_or_add(d,num);\n    display(num);\n}\n"
  },
  {
    "path": "DP/LCS.cpp",
    "content": "/**\n * @file LCS.cpp\n * @author Nisarg\n * @brief Longest comman Subsequence in given two strings\n * NOT HERE APPLICABLE:  // By iterating in reverse order in the inner loop. we can further optmized on space to use single dp array/\n * ex. Soln 4: https://leetcode.com/problems/partition-equal-subset-sum/editorial/\n * \n */\n\n#include<bits/stdc++.h>\n\nusing namespace std;\n\nvoid LCS(string a, string b) {\n    int n = a.size(), m = b.size();\n\n    vector<vector<int> > dp(n+1, vector<int> (m+1, 0));\n\n    for(int i = 1; i <= n; i++) {\n        for(int j = 1; j <= m; j++) {\n            if(a[i-1] == b[j-1]) {\n                dp[i][j] = dp[i-1][j-1] + 1;\n            }\n            else {\n                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);\n            }\n            cout << dp[i][j] << \" \";\n        }\n        cout << endl;\n    }\n\n    cout << \"Longest comman string's length is \" << dp[n][m] << endl;\n\n    int i = n+1, j = m+1;\n    string ans = \"\";\n    while (i > 0 || j > 0) {\n        if (a[i-1] == b[j-1]) {\n            ans += a[i-1];\n            i--; j--;\n        }\n        else {\n            if (dp[i-1][j] < dp[i][j-1]) \n                j--;\n            else \n                i--;\n        }\n    }\n\n    reverse(ans.begin(), ans.end());\n    cout << \"Longest common subsequence is \" << ans << endl;\n}\n\nvoid LCS_SpaceOptmized(string a, string b) {\n    int n = a.size(), m = b.size();\n\n    vector<int> dp(m+1, 0);\n    vector<int> prev(m+1, 0);\n\n    for(int i = 1; i <= n; i++) {\n        for(int j = 1; j <= m; j++) {\n            if(a[i-1] == b[j-1]) {\n                dp[j] = prev[j-1] + 1;\n            }\n            else {\n                dp[j] = max(dp[j-1], prev[j]);\n            }\n        }\n        prev = dp;\n    }\n\n    cout << \"Longest comman string's length is \" << prev[m] << endl;\n}\n\nint main() {\n\n    string str1 = \"abcda\";\n    string str2 = \"abcbcba\";\n\n    int m = str1.length();\n    int n = str2.length();\n\n    LCS(str1, str2); \n    LCS_SpaceOptmized(str1, str2);\n\n    return 0;\n}\n"
  },
  {
    "path": "DP/LIS.cpp",
    "content": "/*\nLongest Increasing Subsequence\nComplexity for LIS Algo -> O(NlogN)  \nN-number of elements\n*/\n\n#include<bits/stdc++.h>\nusing namespace std;\n\n// NOTE : aux is not necesserily the LIS but its length is same as LIS\nint length_LIS(int arr[], int n)\n{\n    vector<int> aux;    //auxiliary vector stores the array elements likely to be LIS \n    for(int i = 0; i < n; i++) \n    {\n        // Change lower_bound to upper_bound for non-decreasing subsequence \n        auto itr = lower_bound(aux.begin(), aux.end(), arr[i]);\n        if (itr == aux.end()) \n            aux.push_back(arr[i]); // No element is larger than arr[i]\n        else \n            *itr = arr[i]; // replace the element in aux with elemwnt just smaller than it.\n    }\n  return aux.size();\n\n}\n\n// This is O(n^2) soln which can be eventually used to find the the exact LIS\nint lengthLIS1(vector<int> arr) {\n\tint n = arr.size();\n\tvector<int> dp(n, 1); // dp[i] = 1 as LIS can be itself\n\n\tfor(int i=0; i<n; i++) {\n\t\tfor (int j=0; j<i; j++) {\n\t\t\tif(arr[j] < arr[i] ) \n\t\t\t\tdp[i] = max(dp[i], arr[j]+1);\n\t\t}\n\t}\n\treturn dp[n-1];\n}\n\n// We can get exact LIS by using parent array.\nvoid find_LIS(int arr[], int n) {\n\tvector<int> dp(n, 1); // dp[i] = longest sub seq till i where ith element is part of it\n\tint ans = 0;\n\n\tfor (int i = 0; i < n; i++) {\n\t\tfor (int j = 0; j < i; j++) {\n\t\t\tif (arr[i] > arr[j])\n\t\t\t\tdp[i] = max(dp[i], dp[j] + 1);\n\t\t}\n\t}\n\n\tfor(int i = 0; i < n; i++)\n\t\tans = max(ans, dp[i]);\n\n\tcout << \"Length of LIS is \" << ans << endl;\n}\n\n// Time Complexcity O(N log N)\nvoid find_LIS_Optimizd(int arr[],int n)\n{\n    vector<int> aux(n, 0);\n\tvector<vector<int>> parent(n);\n\n\taux[0] = arr[0];\n\n\tparent[0].push_back(arr[0]);\n\tint aux_size = 1;\n\tfor (int i = 1; i < n; i++) {\n\t\tauto it =lower_bound(aux.begin(), aux.begin() + aux_size, arr[i]);\n\n\t\tif (it == aux.begin() + aux_size) {\n\t\t\taux[aux_size] = arr[i];\n\t\t\t\t\t\t\n\t\t\tparent[aux_size] = parent[aux_size - 1];\n\t\t\tparent[aux_size].push_back(arr[i]);\n\t\t\taux_size++;\n\t\t}\n\t\telse {\n\t\t\tif (*it != arr[i]) {\n\t\t\t\taux[it- aux.begin()] = arr[i];\n\t\t\t\t\n\t\t\t\tparent[it - aux.begin()][parent[it - aux.begin()].size() - 1] = arr[i];\n\t\t\t}\n\t\t}\n\t}\n\n\tcout << \"length \" << aux_size << endl;\n\n\tfor (auto x : parent[aux_size - 1]) {\n\t\tcout << x << \" \";\n\t}\n}\n \nint main()\n{\n    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };\n    int n= sizeof(arr)/sizeof(int);\n    \n    // Strictly increasing sub sequence\n    cout << \"Length of LIS is :\" << length_LIS(arr,n) << endl;\n\n    // Print the LIS\n    length_LIS(arr,n);\n\tfind_LIS(arr, n);\n}\n\n// Intersting question :\n// Given arr1[N], arr2[M]   1<M<N<10^5\n// Find minimum elements you need to add in arr1 such that arr2 is a subsequence of arr1?\n// Soln: Codenation 1 april 2020 : hint(use maps, LIS)\n"
  },
  {
    "path": "DP/LongestPalindromicSubstring.cpp",
    "content": "#include<bits/stdc++.h>\nusing namespace std;\n\n/* solution is based on gap strategy\nReference  --> https://www.youtube.com/watch?v=WpYHNHofwjc\n\nEvery diagonal of the matrix can be uniquely identified by a gap value which represents the gap between i and j \nThe gap 0 basically represents the individual elements which are themselves palindromes\nex. str = abcda  gaps = a | b | c | d | a ==> 4 gaps (cnt of |)\nNow for any particular i,j it is a palindrome if str from i+1 to j-1 is a palindrome and characters at i and j are equal\nSo, dp[i][j] = dp[i+1][j-1] && str[i]==str[j]\nHere dp[i+1][j-1] represents the diagonally lower element which we have already computed in previous gap iterations\n\n*/\n\nclass Solution {\npublic:\n    string longestPalindromeicSubString(string s) {\n        int n = s.length();\n        bool dp[n][n];\n        memset(dp,false,sizeof(dp));\n        int start = -1;\n        int end = -1;\n        for(int gap=0;gap<n;gap++) // gap betn 1st and last element of substring\n        {\n            for(int i=0,j=gap ; j<n ; i++,j++)\n            {\n                if(gap==0)\n                {\n                    dp[i][j] = true;\n                }\n                \n                else if(gap==1)\n                {\n                    dp[i][j] = (s[i]==s[j]);\n                }\n                \n                else\n                {\n                    \n                    dp[i][j] = (s[i]==s[j] && dp[i+1][j-1]);\n                }\n                \n                if(dp[i][j])\n                {\n                    start = i;\n                    end = j;\n                }\n            }\n        }        \n        return s.substr(start,end-start+1);   \n    }\n};\n\n\n/*\n* Alternte Soln can be made from observation that palindrome has same elements from center.\n* So choose center and find left of center and right of center as 2 pointers compare and get length.\n* Optimization - if(isPalindrome(i,j)) is true and S[i-1] == S[j+1] then isPalindrome(i-1,j+!1) is also true.\n* This operation is to be done for odd as well as even. O(n) Time and O(1) Space.\n*/\n"
  },
  {
    "path": "DP/LongestPanlidromicSubsequence.cpp",
    "content": "/**\n * @file LongestPanlidromicSubsequence.cpp\n * @author Nisarg Gogate\n * @brief Find Longest palindrome subsequence\n * Or Find k -palindrome. Remove at max k characters such that the string formed is a palindrome.\n */\n\n#include <bits/stdc++.h>\n\nusing namespace std;\n\n// Longest common sequence between two strings\n// If a[i] == b[j] dp[i][j] = dp[i-1][j-1] + 1; else max(dp[i-1][j], dp[i][j-1])\nint LCS(string a, string b, int n, int m)\n{\n    vector<vector<int> > dp(n + 1, vector<int>(m + 1, 0));\n    for (int i = 1; i <= n; i++)\n    {\n        for (int j = 1; j <= m; j++)\n        {\n            if (a[i - 1] == b[j - 1])\n                dp[i][j] = 1 + dp[i - 1][j - 1];\n            else\n                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);\n        }\n    }\n    return dp[n][m];\n}\n\n// Trying to mimic the above code using same thing using two pointers\nint longestPalindromeSubseq(string str)\n{\n    int i, j, n = str.size();\n    vector<vector<int> > dp(n + 1, vector<int>(n + 1, 0)); // dp[i][j] denotes the string i to j (inclusive)\n    for (i = n - 1; i >= 0; i--)\n    {\n        dp[i][i] = 1;\n        for (j = i+1; j < n; j++)\n        {\n            dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);\n            if (str[i] == str[j])\n            {\n                dp[i][j] = max(dp[i][j], dp[i + 1][j - 1] + 2);\n            }\n        }\n    }\n    return dp[0][n-1];\n}\n\n// Optimized above solution to use O(N) space\nint longestPalndromeSubsequenceOptimzed(string str) {\n     int n = str.size();\n        vector<int> dp(n, 0), dpPrev(n, 0); // prev denotes the prev row of above solution.\n        for (int i = n - 1; i >= 0; --i) {\n            dp[i] = 1;\n            for (int j = i+1; j < n; ++j) {\n                if (str[i] == str[j]) {\n                    dp[j] = dpPrev[j-1] + 2;\n                } else {\n                    dp[j] = max(dpPrev[j], dp[j-1]);\n                }\n            }\n            dp.swap(dpPrev);\n        }\n        return dpPrev[n-1];\n}\n\nint longestPalindromeSubseqUsingLCS(string s)\n{\n    string s2 = s;\n    reverse(s2.begin(), s2.end());\n    return LCS(s, s2, s.size(), s.size());\n}\n\nint main()\n{\n    string str = \"abccefba\";\n    cout << \"Longest Palindromic subseq using LCS: \" << longestPalindromeSubseqUsingLCS(str) << endl;\n    cout << \"Longest Palindromic subseq: \" << longestPalindromeSubseq(str) << endl;\n    cout << \"Longest Palindromic subseq with O(N) Space Optmization: \" << longestPalndromeSubsequenceOptimzed(str) << endl;\n}"
  },
  {
    "path": "DP/MatrixChainMulti.cpp",
    "content": "// We use this techinique when we have to put brackets in the given list based on some condn.\n// This solution is used when the order in which we pick a element determines the answer.\n\n// Very good que: https://leetcode.com/problems/burst-balloons/\n"
  },
  {
    "path": "DP/PalindromicCuts.cpp",
    "content": "/**\n * @file PalindromicCut.cpp\n * @author Nisarg Gogate\n * @brief Cases when we want to divide array/string into parts and maximize/minimize\n *  something about those parts. We can try MCM\n *\n * Ex. Find min numbers of cuts needed such that each substring is a palindrome.\n * @ref https://leetcode.com/problems/palindrome-partitioning-ii/description/\n */\n\n#include <bits/stdc++.h>\n\nusing namespace std;\n\nint SIZE = 2002;\nvector<vector<int>> dp(SIZE, vector<int>(SIZE, -1));\n\nbool isPalindrome(string str)\n{\n    int i = 0, j = str.size() - 1;\n    while (i < j)\n    {\n        if (str[i] != str[j])\n            return false;\n        i++, j--;\n    }\n    return true;\n}\n\n/**\n * @brief Usually MCM time complexcity is O(n^3) but here as we are checking if it's\n * a palindrome time complexcity is O(n^4)\n */\nint findCuts(string str, int l, int r)\n{\n    if (dp[l][r] != -1)\n        return dp[l][r];\n\n    // String can't be cut if it's length is already less than 1\n    if (l >= r)\n        return dp[l][r] = 0;\n\n    if (isPalindrome(str.substr(l, r - l + 1)))\n        return 0;\n\n    int ans = r - l;\n\n    // NOTE: k should not be equal to r to avoid inf loop\n    for (int k = l; k < r; k++)\n    {\n        int left = dp[l][k] == -1 ? findCuts(str, l, k) : dp[l][k];\n        int right = dp[k + 1][r] == -1 ? findCuts(str, k + 1, r) : dp[k + 1][r];\n\n        ans = min(ans, left + right + 1);\n    }\n    return dp[l][r] = ans;\n}\n\n\n\n/**\n * @brief Idea is to find if a string is palindrom or not in O(1) using dp\n * Also, we don't really need to know number of plindromes between i and j.\n * \n * Here dp[i] represents number of palindromes from 0->i.\n * So, dp[i] = dp[k] + 1 where k->i is a plindrome.\n * \n * Time Complexcity: O(n^2), Space Complexcity: O(n^2)\n */\nint findCutsOptimized(string str) {\n    int n = str.size();\n    vector<int> dp(n, 0); \n    vector<vector<bool>> isPalindrome(n, vector<bool>(n, false)); \n\n    for (int len = 1; len <= n; ++len) {\n        for (int i = 0; i <= n - len; ++i) {\n            int j = i + len - 1;\n            if (str[i] == str[j] && (len <= 2 || isPalindrome[i + 1][j - 1])) {\n                isPalindrome[i][j] = true;\n            }\n        }\n    }\n\n    for (int i = 0; i < n; ++i) {\n        if (isPalindrome[0][i]) {\n            dp[i] = 0; \n        } else {\n            dp[i] = i; // suppose we need to cut at each index\n            for (int j = 0; j < i; ++j) {\n                if (isPalindrome[j + 1][i]) {\n                    dp[i] = min(dp[i], dp[j] + 1); \n                }\n            }\n        }\n    }\n\n    return dp[n - 1];\n}\n\n/**\n * @brief We take advantage of property that palindrome is same from front and back\n * We \n *\n * Time Complexcity: O(n^2), Space Complexcity: O(n)\n * \n * @param str \n * @return int \n */\nint findCutsMostOptimized(string str) {\n    int n = str.size();\n    vector<int> dp(n+1);\n    for (int i = 0; i <= n; i++) dp[i] = i-1; // note dp[0] will be set -1. This helps us with a cleaner code\n    for(int mid = 0; mid < n; mid++){\n    //palindrome of odd lengths 1,3,5...\n    for(int len = 0; mid-len >= 0 && mid+len < n; len++)\n        if(str[mid-len] == str[mid+len])\n            dp[mid+len+1] = min(dp[mid+len+1], dp[mid-len]+1);\n    //palindrome of even lengths 2,4,6...\n    for(int len = 0; mid-len >= 0 && mid+len+1 < n; len++)\n        if(str[mid-len] == str[mid+len+1])\n            dp[mid+len+2] = min(dp[mid+len+2], dp[mid-len]+1);\n    }\n    return dp[n];\n    \n}\n\nint main()\n{\n    string str = \"aabacd\";\n    cout << \"Minimum cuts needed \" << findCuts(str, 0, str.size() - 1) << \"\\n\";\n}\n"
  },
  {
    "path": "DP/digit_dp.cpp",
    "content": "// Reference -> https://www.youtube.com/watch?v=heUFId6Qd1A\n// F(x) returns boolean value\n// General -> How many integers x in range [0,R] obey F(x)\n// Example -> Find cnt of numbers betn L and R which have a sum of digits = x\n// 1 <= L <= R <= 10^18\n// 1 <= X <= 180\n#include<bits/stdc++.h>\nusing namespace std;\n\n// Max no of dights in a number be 100(Not needed)\nint dp[101][181][2];\n// boolena value tight stores checks if we can place any number at indx(R.size()-n) or we need we can place till ub\nint digit_dp(string R,int n,int sum,bool tight)\n{\n    if(sum < 0)\n        return 0;\n    if(n==0)\n    {\n        if(sum == 0)\n            return 1;\n        return 0;\n    }\n\n    if(dp[n][sum][tight] != -1)\n        return dp[n][sum][tight];\n\n    // ub is upper bound till which digit we can use at that particular index\n    int ub = 9,ans=0;\n    if(tight)\n        ub = (R[R.size()-n]-'0');\n    for(int i=0;i<=ub;i++)\n    {\n        // Once a number is non tight it won't ever be tight in future\n        // A tight will be tight only if we keep on passing the higest number possible at that indx\n        ans += digit_dp(R,n-1,sum-i,tight&(i==ub));\n    }\n    return dp[n][sum][tight] = ans;\n}\n\nint main()\n{\n    string L = \"\";\n    string R = \"490447834749\";\n    int x = 20;\n    memset(dp,-1,sizeof dp);\n    cout<<digit_dp(R,R.size(),x,1);\n}"
  },
  {
    "path": "DP/travelling_salesman_prob.cpp",
    "content": "// Reference -> https://www.youtube.com/watch?v=QukpHtZMAtM&list=PLb3g_Z8nEv1icFNrtZqByO1CrWVHLlO5g&index=4\n// Reference -> https://www.thecrazyprogrammer.com/2017/05/travelling-salesman-problem.html\n// Time Complexcity -> O(n^2 * 2^n)\n// Space Complexcity -> O(2^n * n)\n// NOTE : Whenever we feel a need to pass a subset of set we can use this technique of digit dp\n// Que. Find minimum distance to travel if travellers wishes to visit every city atleast once and reach back to his starting location at the end\n#include<bits/stdc++.h>\nusing namespace std;\n\n#define MAX 9999\n\nint n=4; // Number of the places want to visit\n\n //Next distan array will give Minimum distance through all the position\nint distan[10][10] = {                \n                    {0, 10, 15, 20},\n                    {10, 0, 35, 25},\n                    {15, 35, 0, 30},\n                    {20, 25, 30, 0}\n};\n\nint all_visited = (1<<n) -1;\nint dp[16][4];\n\n\nint  TSP(int visited,int position)\n{\n    // Initially checking whether all the places are visited or not\n    if(visited==all_visited)\n        return distan[position][0];\n\n    if(dp[visited][position]!=-1)\n        return dp[visited][position];\n    \n    // init\n    int answer = MAX;\n\n    // chack for each city\n    for(int city=0;city<n;city++)\n        if((visited&(1<<city))==0)  // is the city visited check\n            answer = min(answer, distan[position][city] + TSP( visited|(1<<city),city));\n\n    return dp[visited][position] = answer;\n}\n\nint main()\n{\n    memset(dp,-1,sizeof dp);\n    cout<<\"Minimum Distance Travelled by traveller is \"<<TSP(1,0);\n\n    return 0;\n}"
  },
  {
    "path": "Geometry/anglecoverted.cpp",
    "content": "// given question : https://leetcode.com/discuss/interview-question/5567668/Google-Interview-Onsite-1\n\n"
  },
  {
    "path": "Graph/BFS.cpp",
    "content": "#include<bits/stdc++.h>\n// Time Complexity: O(V + E)\n// A slight modification of question: Find 2nd fastest way of reaching from source to destination. in Undirected ascyclic graph.\n// Fastest way is using normal BFS. Here we'll ne two dist arrays. dist1[]stroring 1st time we encounter a num. dist2[] we encountering 2nd time.\n//https://www.youtube.com/watch?v=_rnQKrA9xzA&t=436s&ab_channel=codestorywithMIK\nusing namespace std;\n#define LIM 1007\n\nvector<int> adj[LIM];\n// vector<int> dist(LIM,-1);\n// vector<int> parent(LIM,-1);\nint visited[LIM];\n\nvoid addEdge(int u, int v) \n{ \n    adj[u].push_back(v);\n    adj[v].push_back(u);\n} \n\nvoid bfs(int src)\n{\n    queue<int> q;\n    int d=0;\n    // dist[src] = d;\n    // parent[src] = -1;\n    q.push(src);\n    visited[src]=true;\n    while(!q.empty())\n    {\n        int u = q.front();\n        q.pop();\n\n        cout<<u<<\" \";\n        for(int v : adj[u])\n        {\n            if(!visited[v])\n            {\n                // dist[v] = dist[u] + 1;\n                // parent[v] = u;\n                \n                visited[v]=true;    //NOTE : We put visited here inside the inner loop\n                q.push(v);\n            }\n                \n        }\n    }\n}\n\n\nint main()\n{\n    int V,i,src,u,v,wt,E;\n\n    cout<<\"Enter number of vertices and edges: \";\n    cin>>V>>E;\n    \n\n    for(i=0;i<E;i++)\n    {\n        cout<<i+1<<\". Enter vertex name u and v:  \";\n        cin>>u>>v;\n        addEdge(u,v);\n    }\n   \n\n    cout<<\"Enter source node for iterative bfs: \";\n    cin>>src;\n    cout<<\"BFS=> \";\n    bfs(src);\n    cout<<endl;\n\n\n}\n"
  },
  {
    "path": "Graph/Bellman_ford(Negative_weights).cpp",
    "content": "/*\nReference -> https://www.youtube.com/watch?v=FtN3BYH2Zes\nMinimum distance of src from every other node present in graph\nComplexity for Bellman Ford's Algo -> O(E*V)  \nE-Edges V-Vertices\n*/\n#include<bits/stdc++.h>\n#define LIM 3000\n#define INF 1e5+3\n\nusing namespace std;\n\n\n//NOTE: Here reprentation of graph is done a bit differnetly \ntypedef pair<int,int> pii;\n\nvector<vector<int>> G(LIM,vector<int>(3));\nvector<int> min_dist(LIM,INF);\nint V,E;\n\n/*\nIMP NOTE: If there is a cycle with total sum negative then this algo WON'T WORK\nWe baically relax the edges V-1 times\n*/\nvoid bellman_ford(int src)\n{\n    min_dist[src] = 0;\n    int u,v,k;\n    for(k=0;k<V-1;k++)\n    {\n        for(auto itr : G)\n        {\n            int u = itr[0];\n            int v = itr[1];\n            int wt = itr[2];\n\n            min_dist[v] = min(min_dist[v],min_dist[u]+wt);\n        }\n    }\n\n    // If the min min_dist is still changing even after V-1 iterstions means there is no soln.\n    for(auto itr : G)\n    {\n        int u = itr[0];\n        int v = itr[1];\n        int wt = itr[2];\n\n        if(min_dist[v] > min_dist[u]+wt)\n        {\n            cout << \"There is a negtive cycle\\n\";\n            break;\n        }\n    }\n    \n}\n\nint main()\n{\n    int i,src=0,u,v,wt;\n\n    cout<<\"Enter number of vertices and edges: \";\n    cin>>V>>E;\n    cout<<endl;\n\n    for(i=0;i<8;i++)\n    {\n        cout<<\"Enter vertex name u , v and weight: \";\n        cin>>u>>v>>wt;\n\n        G[i][0] = u;\n        G[i][1] = v;\n        G[i][2] = wt;\n    }\n    \n    cout<<\"Enter the source node: \";\n    cin>>src;\n    bellman_ford(src);\n    cout<<endl;\n\n    cout<<\"Min distace all nodes from \"<<src<<\"is:\\n\";\n    for(int i=0;i<V;i++)\n        cout<<i<<\" : \"<<min_dist[i]<<endl;\n}"
  },
  {
    "path": "Graph/Bipartite_Coloring.cpp",
    "content": "#include<bits/stdc++.h>\n\nusing namespace std;\n#define LIM 1007\ntypedef enum {WHITE,GREY,BLACK} col;\n// we try ro color whole graph in 2 colors grey and black\n\n\nvector<int> adj[LIM];\nvector<col> color(LIM,WHITE);\n\n\nvoid addEdge(int u, int v) \n{ \n    adj[u].push_back(v);\n    adj[v].push_back(u);\n} \n\nvoid bfs()\n{\n    queue<int> q;\n    int d=0;\n\n    for(int i=1;i<LIM;i++)\n    {\n        // if we find a new part of G\n        if(color[i] == WHITE)\n            q.push(i);\n\n        while(!q.empty())\n        {\n            int u = q.front();\n            q.pop();\n\n            // If no color is given give a random color\n            if(color[u] == WHITE)\n                color[u] = GREY; \n\n            for(int v : adj[u])\n            {\n                if(color[v] == WHITE)\n                {\n                    if(color[u] == GREY)\n                        color[v] = BLACK;\n                    else\n                        color[v] = GREY;\n\n                    q.push(v);\n                }\n                else\n                {\n                    // If adjecent nodes have same color\n                    if(color[u] == color[v])\n                    {\n                        cout << \"IMPOSSIBLE\";\n                        return;\n                    }\n                }\n                    \n            }\n        }\n    }\n    cout << \"Color for ith node is: \" << endl;\n    for(int i=1;i<LIM;i++)\n    {\n        cout << i<< \" \" <<color[i];\n    }\n\n}\n\n\nint main()\n{\n    int V,i,src,u,v,wt,E;\n\n    cout<<\"Enter number of vertices and edges: \";\n    cin>>V>>E;\n    \n\n    for(i=0;i<E;i++)\n    {\n        cout<<i+1<<\". Enter vertex name u and v:  \";\n        cin>>u>>v;\n        addEdge(u,v);\n    }\n   \n\n    // Printing color of each node in graph\n    bfs();\n\n\n\n}"
  },
  {
    "path": "Graph/Bipartite_matching.cpp",
    "content": "/**\n * @file Bipartite_matching.cpp\n * @author Nisarg\n * @brief Question: Given n job appplicants and m jobs. Given ith applicant with letter from jth job\n * Find maximum number of job applicants which can get a job. jobs[i][j] = 1 / 0\n *\n * @ref: https://www.geeksforgeeks.org/maximum-bipartite-matching/\n * @ref: https://cp-algorithms.com/graph/kuhn_maximum_bipartite_matching.html\n * @ref: https://leetcode.com/problems/maximum-number-of-accepted-invitations/solutions/1978859/python-hungarian-algorithm-easy-to-understand/\n */\n\n#include <bits/stdc++.h>\n\nusing namespace std;\n\nint jobs = 6, applicants = 6;\n\nvector<vector<int> > G;\nvector<int> currentMatching(jobs, -1);       // Job i mapped with currentMatching[i] applicant.\nvector<bool> visited(applicants);            // Usual use so that dfs doesn't visit same vertex again\n\n/**\n * Main idea behind the logic is a job applicant will only leave job if he/she gets some other job.\n *\n * @return bool : true a new match is added\n */\n\nbool findMaxBiPartiteMatching(int u) // applicant\n{\n    if (visited[u]) // if applicant is already assigned or checked no need to recheck\n        return false;\n\n    visited[u] = true;\n\n    // Checking if vth job if already selected by some applicant\n    for (auto v : G[u]) {\n        // if current matching is available for v or if v can find some other job\n        // checking if selected applicant for job v can find some other job\n        if ( currentMatching[v] == -1 || findMaxBiPartiteMatching(currentMatching[v]) ) {\n            currentMatching[v] = u;\n            return true;\n        }\n    }\n    return false;\n}\n\nint main()\n{\n    G = {\n            {1, 2}, // Applicant 0 has {1, 2} job offers\n            {0, 3}, // Applicant 1 has {0, 3} job offers \n            {2}, \n            {2, 3}, \n            {}, \n            {5}\n        };\n\n    int ans = 0;\n    for (int applicant = 0; applicant < applicants; applicant++)\n    {\n        visited.assign(applicants, false);\n        if(findMaxBiPartiteMatching(applicant))\n            ans++;\n    }\n\n    cout << \"Max num of G matching with applicants is \" << ans;\n}\n"
  },
  {
    "path": "Graph/DFS.cpp",
    "content": "\n/*\nWe can  peform multisorurce bfs also for the problems of type \n1. there are k hospitals and n cities and they are connected so find closest hostila form each city\nAdd all hospitals as src and do bfs on unvisited nodes so ...\n\nTime Complexity: O(V + E)\n\n*/\n#include<bits/stdc++.h>\n#define LIM 3000\n#define INF 1e5+3\nusing namespace std;\n\nvector<int> adj[LIM];\nbool visited[LIM];\n\nvoid addEdge(int u, int v) \n{ \n    adj[u].push_back(v);\n    adj[v].push_back(u);\n} \n\nvoid dfs_iterative(int src)\n{\n    memset(visited,0,sizeof(visited));\n    stack<int> stck;\n    stck.push(src);\n\n    while(stck.size())\n    {\n        int u=stck.top();\n        stck.pop();\n\n        visited[u]=true;\n        cout<<u<<\" \";        \n\n        for(auto v:adj[u])\n        {\n            if(!visited[v])\n                stck.push(v);\n        }\n    }\n    memset(visited,0,sizeof(visited));\n}\n\n\n\nvoid dfs_recursive(int u)\n{\n    if(visited[u])\n    return ;\n\n    visited[u]=true;\n    cout<<u<<\" \";\n\n    for(int v : adj[u])\n    {\n        if(!visited[v])\n            dfs_recursive(v);\n    }\n}\n\n\n\n\nint main()\n{\n    int V,i,src,u,v,wt;\n\n    cout<<\"Enter number of vertices and edges: \";\n    cin>>V>>E;\n    \n\n    for(i=0;i<E;i++)\n    {\n        cout<<i+1<<\". Enter vertex name u and v:  \";\n        cin>>u>>v;\n        addEdge(u,v);\n    }\n   \n\n    cout<<\"Enter source node for iterative dfs: \";\n    cin>>src;\n    cout<<\"Iterative_DFS=> \";\n     dfs_iterative(0);\n     cout<<endl;\n\n    cout<<\"Enter source node for recursive dfs: \";\n    cin>>src;\n    cout<<\"Recursive_DFS=> \";\n}\n"
  },
  {
    "path": "Graph/FloydWarshall.cpp",
    "content": "/**\n * @file FloydWarshall.cpp\n * @author Nisarg\n * @brief Multi Source shortest path algorithm. Find shortest paths from all nodes to all other nodes.\n * Logic: dist[i][j] =  min (dist[i][j]],dist[i][k] + dist[k][j])\n * Time complexity: O(V^3)\n * @date 2024-07-28\n */\n\n#define INF 1e5+3\n\n#include<bits/stdc++.h>\n\nusing namespace std;\n\nvoid findShortestDist(vector<vector<int>>& matrix) {\n    int n = matrix.size(), i, j, k;\n\n    // initialize matrix with INF dist where no roads are available\n    // initialize matrix with 0 dist where i == j\n    for (i = 0; i < n; i++) {\n        for (j = 0; j < n; j++) {\n            if (matrix[i][j] == -1) matrix[i][j] = INF;\n            if (i == j) matrix[i][j] = 0;\n        }\n    }\n\n    // Floyd Warshall's algorithm\n    for(k = 0; k < n; k++) \n        for(i = 0; i < n; i++) \n            for(j = 0; j < n; j++) \n                matrix[i][j] = min(matrix[i][j], matrix[i][k] + matrix[k][j]);\n}\n\n\nint main() {\n    int V = 4;\n    vector<vector<int> > matrix(V, vector<int>(V, -1));\n\tmatrix[0][1] = 2;\n\tmatrix[1][0] = 1;\n\tmatrix[1][2] = 3;\n\tmatrix[3][0] = 3;\n\tmatrix[3][1] = 5;\n\tmatrix[3][2] = 4;\n\n    findShortestDist(matrix);\n    \n\n    cout << \"Following matrix shows the shortest distances between every pair of vertices \\n\";\n    for (int i = 0; i < V; i++) {\n        for (int j = 0; j < V; j++) {\n            if (matrix[i][j] == INF)\n                cout << \"INF \";\n            else\n                cout << matrix[i][j] << \" \";\n        }\n        cout << endl;\n    }\n}"
  },
  {
    "path": "Graph/README.md",
    "content": "# Graphs\n\nMinimum Spanning Tree\n- **Prim's Algorithm**: Add `{wt, node}` to min heap to visit all nodes only once.\n\n\nShortest Distance from `src` node to all nodes in Graph\n- **Dijkstra Algorithm**: Greedy approach choose the closest node from each node and store in min heap. *[+ve weights]*.\n- **Bellman Ford**: Loop V times over all edges in graph and set `dist[v] = min(dist[v], dist[u]+wt(u,v))`. *[-ve weights]*\n\nShortest Distance between all pairs of nodes in Graph\n- **Floyd Warshall Algorithm**:  For every path which passes through k, `dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])` \n\nDungeon Break: https://leetcode.com/problems/dungeon-game/description/ Really good question\n"
  },
  {
    "path": "Graph/cycleDetection.cpp",
    "content": "/**\n * @file cycleDetection.cpp\n * @author Nisarg\n * @date 2024-07-27\n * \n * Detect cycle in directed and adirected graphs\n */\n\n#include<bits/stdc++.h>\n#define LIM 1007 \n\nusing namespace std;\n\nvector<int> G[LIM];\n\n// Other way of doing this is by bipartiate coloring\nbool isCyclicInDirectedGraph(int n, vector<int> inDegree) {\n\n    int i;\n    queue<int> q; // NOTE: it stores the topo sorted order\n\n    for(i=0;i<inDegree.size();i++)\n        if(inDegree[i] == 0)\n            q.push(i);\n    \n    while(!q.empty()) {\n        int u = q.front();\n        q.pop();\n\n        for(auto v : G[u]) {\n            inDegree[v]--;\n            if(inDegree[v] == 0)\n                q.push(v);\n        }\n    }\n\n    // Nodes with more than 1 in degree must be in cycle so they were never inserted in queue.\n    for(i=0;i<n;i++)\n        if(inDegree[i]!= 0)\n            return true;\n\n    return false;\n}\n\n\n\nint main() {\n    int n, edges, u, v;\n    cout << \"Enter the number of vertices and edges: \";\n    cin >> n >> edges;\n\n    vector<int> inDegree(n);\n\n    for(int i=0;i<edges;i++) {\n        cin >> u >> v;\n        G[u].push_back(v);\n        inDegree[v]++;\n    }\n\n    if(isCyclicInDirectedGraph(n, inDegree))\n        cout << \"Cycle found in directed Graph\" << endl;\n}"
  },
  {
    "path": "Graph/dijkstra.cpp",
    "content": "/*\nA minimum distance of src from every other node present in graph with all non-negative weights (optimized algo) OR Negative weighted a-cyclic graph (Non-optimized Algo)\nComplexity for dijktra's Algo -> O((V + E) log V)\nE-Edges V-Vertices\n\nWe may add same node multiple times, hence total elements in a heap might be E. Hence, log(E).\nIntreasting thing is to E = V*(V-1) => 2*log(V).\n\nSlight modification: Think of adding a virtual node which joins an edge to each node. [Similar to multi source BFS]\n\nDikjtras can be applied 3-4 times... you reverse graph... node a to src and dest dist\nhttps://leetcode.com/problems/minimum-weighted-subgraph-with-the-required-paths/description/\n*/\n#include<bits/stdc++.h>\n#define LIM 3000\n#define INF 1e5+3\ntypedef pair<int,int> pii;\nusing namespace std;\n\n//NOTE: Global variables are initailized to 0\nvector<pii> adj[LIM];\nvector<int> min_dist(LIM,INF);\n\n//Each node in adj list represnts vertex and weight\nvoid addEdge(int u, int v, int wt) \n{ \n    adj[u].push_back({v,wt});\n    adj[v].push_back({u,wt});\n} \n\nvoid dijktra(int src)\n{\n    //MIN HEAP\n    // Keep distace or weight in first plce and indx in second\n    priority_queue<pii, vector<pii>, greater<pii> > pq;\n\n    for(int i=0;i<LIM;i++)\n        min_dist[i]=INF;                //Init to infinity\n\n    min_dist[src]=0;\n\n    pq.push({0,src});\n    while(pq.size())\n    {\n        \n        int curr = pq.top().second;\n        pq.pop();\n\n        // Optimized to not traverse children if minDist which was encountered earlier was better\n        // This helps avoid traversing children if we already have a miniDist smaller traversed earlier\n        if( curr > min_dist[curr])\n            continue;\n\n        for(auto u : adj[curr])\n        {\n            int next = u.first;\n            int d = u.second;\n            \n            //If previous distance is more than the new distance\n            if(min_dist[next] > min_dist[curr]+d)\n            {\n                pq.push({ d + min_dist[curr], next });\n                min_dist[next] = d+ min_dist[curr];\n            }                \n        }\n    }\n\n}\n\nint main()\n{\n    int V,i,E,src,u,v,wt;\n\n    cout<<\"Enter number of vertices and edges: \";\n    cin>>V>>E;\n    cout<<endl;\n\n    for(i=0;i<E;i++)\n    {\n        cout<<\"Enter vertex name u , v and weight: \";\n        cin>>u>>v>>wt;\n        addEdge(u,v,wt);\n    }\n    \n    cout<<\"Enter the source node: \";\n    cin>>src;\n    dijktra(src);\n    cout<<endl;\n\n    cout<<\"Min distace all nodes from \"<<src<<\"is:\\n\";\n    for(int i=0;i<V;i++)\n        cout<<i<<\"-\"<<min_dist[i]<<endl;\n}\n"
  },
  {
    "path": "Graph/prims_algo.cpp",
    "content": "/*\nMinimum Spanning tree is (minimum sum) tree with V-1 edges\nTotal sum of all the edges must be minimum in O(ElnV)\nE-Edges V-Vertices\n\nNOTE : We can't find minimal spanning tree using distra's algo\n    2\nO-------A\n    10 / \\ 11\n      /   \\\n     B-----C\n        2\nUsing dijstar's if we start from O we will have edges O-A,A-B,A-C \nas from O-B dist = 12/15 and O-C distance = 14/13\n*/\n#include<bits/stdc++.h>\n#define LIM 3000\n#define INF 1e5+3\nusing namespace std;\n\ntypedef pair<int, int> pii;\nvector<pii> adj[LIM];\nbool visited[LIM];\n\n//Each node in adj list represnts vertex and weight\nvoid addEdge(int u, int v, int wt) \n{ \n    adj[u].push_back({v,wt});\n    adj[v].push_back({u,wt});\n} \n\nint prim()\n{\n    //MIN HEAP\n    priority_queue<pii, vector<pii>, greater<pii> > pq;\n\n    int mst_sum=0;\n    int curr_dist=0;\n\n    //Lets assume we start from 0th node\n    pq.push({curr_dist,0});\n\n    while(pq.size())\n    {\n        //we get the smallest possible distance on top of pq\n        int curr_node=pq.top().second;\n        int curr_dist=pq.top().first;\n\n        pq.pop();\n\n        //if already visited the it must be connected to smallest possible value\n        if(visited[curr_node])\n        continue;\n\n        visited[curr_node]=true;\n        mst_sum += curr_dist;\n\n        for(auto u : adj[curr_node])\n        {\n            //We push in all the possible adjecent nodes from curr_node\n            if(!visited[u.first])\n                pq.push({u.second,u.first});\n        }\n    }\n    return mst_sum;\n}\n\nint main()\n{\n    int V,E,i,src,u,v,wt;\n\n    cout<<\"Enter number of vertices and edges: \";\n    cin>>V>>E;\n    cout<<endl;\n\n    for(i=0;i<E;i++)\n    {\n        cout<<\"Enter vertex name u , v and weight: \";\n        cin>>u>>v>>wt;\n        addEdge(u,v,wt);\n    }\n \n    \n    cout<<\"Minimum spanning tree sum: \";\n    cout<<prim()<<endl;\n\n}\n"
  },
  {
    "path": "Graph/topological_sort.cpp",
    "content": "// Not necessarily unique\n// Acyclic graph and directed graph\n/* \n    Que -> https://cses.fi/problemset/task/1679 \n    Time complexcity -> O(V+E)\n    Space Complexcity -> O(V)\n*/\n\n\n// Alternate approach can be looking at the in-degree of each node\n// Step 1: Find in-degree of each node and maintain it in an array\n// step 2: if(indgree[i] == 0) put in queue (bfs) and add it in aur ans array\n// do bfs and which ever element we visit reduce its indegree \n// keep on checking while reducing indegree and if its zero add... REPEAT \n\n#include<bits/stdc++.h>\n#define LIM 3000\n#define INF 1e5+3\ntypedef enum {WHITE,GREY,BLACK} col;    //white-no col\n\nusing namespace std;\n\nint V,E;\nvector<int> G[LIM];\nvector<bool> visited(LIM,false);\nvector<col> color(LIM,WHITE);\n\nbool notIsCyclic(int u)\n{\n    color[u] = GREY;\n\n    bool ans=true;\n\n    for(auto v:G[u])\n    {\n        if(color[v] == GREY)\n            return false;\n        if(color[v] == BLACK)\n            continue;\n\n        ans &= notIsCyclic(v);\n        \n    }\n    color[u] = BLACK;\n    return ans;\n}\n\nvoid dfs(int u, stack<int>& stck)\n{\n    visited[u] = true;\n    for(auto v: G[u])\n        if(!visited[v])\n            dfs(v,stck);\n    // NOTE : We insert element in stack after its dfs traversal.\n    stck.push(u);\n}\n\nint main()\n{\n\tint i,j;\n    cin>>V>>E;\n    \n    for(i=0;i<E;i++)\n    {\n        int u,v;\n        cin >> u >> v;\n        G[u].push_back(v);\n    }\n\n    // Check for any cycle in graph\n    for(i=1;i<=V;i++)\n        if(color[i] == WHITE)\n            if(!notIsCyclic(i))\n            {\n                cout << \"IMPOSSIBLE\\n\";\n                return;\n            }\n\n    // Adding elements to the stack if not visited\n    stack<int> stck;\n    for(i=1;i<=V;i++)\n        if(!visited[i])\n            dfs(i,stck);\n\n    // Actually elements are adding in opposite order of topo sort but we \n    // acces the elements in descending order as its a stack.\n    for(;!stck.empty();stck.pop())\n        cout << stck.top() << \" \";\n    \n\n}"
  },
  {
    "path": "Graph/union_find_algo.cpp",
    "content": "/*\n    Que: Given a list of operation makeFriends(a,b) and areFriends(a,b)\n    These methods makes a and b friends or checks if they are friends.\n    Time  & Space complexcity if done by Graph O(n) & O(n)\n    Time  & Space complexcity in case of disjoint set O(m*4) & O(n)\n        : m is the number of operations being performed on this dijoint set\n    https://leetcode.com/problems/the-earliest-moment-when-everyone-become-friends\n    Ref: https://www.youtube.com/watch?v=Kptz-NVA2RE\n*/\n\n#include <bits/stdc++.h>\n\nusing namespace std;\n\nvector<int> parent; // Keeps track of group representative/parent\nvector<int> sz;     // Keeps track of num of elements in children below this node\n\n// Init the array with each element as it's parent\nvoid init(int n)\n{\n    parent.resize(n);\n    sz.resize(n);\n    for (int i = 0; i < n; i++)\n    {\n        parent[i] = i;\n        sz[i] = 1;\n    }\n}\n\n// Finds parent of x then parent of parent of x and so on...\n// Along with path compression as on return it updates parent[x]\nint find(int x)\n{\n    if (parent[x] == x)\n        return x;\n\n    return parent[x] = find(parent[x]); // remember to call it for parent[x]\n}\n\n// Joins sets of x to y. Based on the rank of parent for minimum time complexcity.\nvoid weightedUnion(int x, int y)\n{\n    int xRoot = find(x);\n    int yRoot = find(y);\n\n    if (xRoot == yRoot)\n        return;\n\n    if (sz[xRoot] < sz[yRoot])\n    {\n        parent[xRoot] = yRoot;\n        sz[yRoot] += sz[xRoot];\n    }\n    else\n    {\n        parent[yRoot] = xRoot;\n        sz[xRoot] += sz[yRoot];\n    }\n    \n}\n\n// n - number of fiends\n// m - number of operations/relations\nint main()\n{\n    int i, n, m;\n\n    cin >> n >> m;\n    init(n);\n    for (i = 0; i < m; i++)\n    {\n        string operation;\n        int x, y;\n        cin >> operation >> x >> y;\n        if (operation == \"makeFriend\")\n        {\n            weightedUnion(x, y);\n        }\n        else if (operation == \"isFriend\")\n        {\n            if(find(x) == find(y)) cout << \"Yes\\n\";\n            else cout << \"No\\n\";\n        }\n    }\n    return 0;\n}\n"
  },
  {
    "path": "Greedy or DP (Problems)/Continuous_subarray_sum.cpp",
    "content": "// Link --> https://leetcode.com/problems/continuous-subarray-sum/\nFind if is there any subarray with sum in multiple of k\n\nbool find(vector<int> arr, int k){\n    set<int> s;\n    int sum=0;\n    for(int i=0;i<arr.size();i++){\n        sum += arr[i];\n        int val = sum%k==0?k:sum%k;\n        if(s.find(val) == s.end())\n            s.insert(val);\n        else\n            return false;\n    }\n    return true;\n}"
  },
  {
    "path": "Greedy or DP (Problems)/Job_scheduling.cpp",
    "content": "// Link --> https://leetcode.com/problems/maximum-profit-in-job-scheduling/\n\n// You're given the startTime, endTime and profit arrays, return the maximum profit \n// you can take such that there are no two jobs in the subset with overlapping time range.\n// 1 <= startTime[i] < endTime[i] <= 10^9\n\n// NOT A GREEDY SOLN\nint jobScheduling(vector<int>& startTime, vector<int>& endTime, vector<int>& profit) {\n    int n = startTime.size();\n    vector<vector<int>> jobs;\n    for (int i = 0; i < n; ++i) {\n        jobs.push_back({endTime[i], startTime[i], profit[i]});\n    }\n\n    // Sort according to end time of jobs\n    sort(jobs.begin(), jobs.end());\n\n    // dp[i] stores maximum profit at time = i\n    map<int, int> dp = {{0, 0}};\n    for (auto& job : jobs) {\n            // Finding the profit at largets end time before current job's start iem \n        int cur = prev(dp.upper_bound(job[1]))->second + job[2];\n        if (cur > dp.rbegin()->second)\n            dp[job[0]] = cur;\n    }\n    return dp.rbegin()->second;\n}\n\n\n// Link -->https://practice.geeksforgeeks.org/problems/job-sequencing-problem-1587115620/1#\n// N jobs takes 1 unit of time to complete and jth job has job[j] as deadline.\n// Find max profit? \n\n/*\n* Sort according to the profits (decreasing)\n* Do the process as late as possible (Close to deadline)\n* U have the ans...\n*/"
  },
  {
    "path": "Greedy or DP (Problems)/Kadane.cpp",
    "content": "// Find max_sum of sub array\n// Question? Why should curr_sum start with arr[i] and not with something before ith index? \n// Assume started from start => Case 1: (some -ve sum) + arr[j] - we will already started from arr[j].\n                             => Case 2: (Some +ve sum) + arr[j] - It's already part of curr_sum.\nint kadane(vector<int> arr) {\n    int n = arr.size(),i,ans_sum=0,curr_sum = arr[0];\n    for(i=1;i<n;i++){\n        curr_sum = max(arr[i],curr_sum+arr[i]);\n        ans_sum = max(ans_sum,curr_sum);\n    }\n    return ans_sum;\n}\n\n// Find maximum product of subarray\n// https://leetcode.com/problems/maximum-product-subarray/\nint maxProductSubarray(vector<int> arr) {\n    int ans = arr[0],max_val=arr[0],min_val=arr[0];\n    for(int i=1;i<arr.size();i++) {\n        if(arr[i] < 0)\n            swap(max_val,min_val);\n        \n        max_val = max(arr[i],max_val*arr[i]);\n        min_val = min(arr[i],min_val*arr[i]);\n        \n        ans = max(ans,max_val);\n    }\n    return ans;\n}\n\n// In such formula based question try to break down the formula\n// Find max value of arr[i]+arr[j]+i-j where i<j\n// https://leetcode.com/problems/best-sightseeing-pair/\nint max_pair(vector<int> arr) {\n    int i,n=arr.size(),prev_max = 0,ans=0;\n    // TRICK - arr[i]+i  + arr[j]-j is to be maximized\n    for(i=0;i<n;i++){\n        ans = max(ans,prev_max+arr[i]-i);\n        prev_max = max(prev_max,arr[i]+i);\n    }\n    return ans;\n}\n\n"
  },
  {
    "path": "Greedy or DP (Problems)/Queue_Reconstruction.cpp",
    "content": "/*Given n peps with [hi,ki] where ki denotes number of peps with height\n* greater than or eqaul to hi to its left in final queue\n* https://leetcode.com/problems/queue-reconstruction-by-height/\n\n* Soln -> Time Complexcity O(n logn)\n*/\n#include<bits/stdc++.h>\nusing namespace std;\n\n// Return The sequence which satisfies the given condition\nvector<pair<int,int>> queue_reconstruction(vector<pair<int,int>> people) {\n    // Observations - \n    // We need to count people with height taller or equal to in front of them\n    // Smaller person is completely irrelevant\n    // For smallest person all persons are greater than him\n    sort(people.begin(),people.end(),[](pair<int,int> p1,pair<int,int> p2){\n        return p1.first>p2.first or\n               (p1.first == p2.first and p1.second<p2.second);\n    });\n    // can be written as compare function as well\n    vector<pair<int,int>> ans;\n    \n    for(int i=0;i<people.size();i++) \n        // We have to insert the person into people[i].second position\n        // as all the k persons before that index are greater than or equal in height as person[i] \n        ans.insert(ans.begin()+people[i].first,people[i]);\n    // Insert function takes in 2 param - position (iterator)  - value\n    \n}"
  },
  {
    "path": "Greedy or DP (Problems)/jump_problem.cpp",
    "content": "// Link : https://leetcode.com/problems/jump-game-ii/\n// Reach from 0th index to nth index with minimum number of jumps\n// arr[i] represents max jump possible from ith index.\n\n#include<bits/stdc++.h>\nusing namespace std;\n\nint min_jump(vector<int> arr)\n{\n    int n = arr.size(),i;\n    int range_of_jump = arr[0]; // This is the index upto which we can reach\n    int max_reachable_index = arr[0];   // Next maximum reachable index from current range (1 more jump will be neede)\n    int jump = 1;\n\n    // We have already made our 1st jump\n    for(i=1;i<n-1;i++)\n    {\n        max_reachable_index = max(arr[i]+i,max_reachable_index);\n\n        // we can't go anyfurther without doing an extra jump\n        if(i == range_of_jump)\n        {\n            range_of_jump = max_reachable_index;\n            jump++;\n        }\n    }\n    return jump;\n}\n\nsigned main()\n{\n    int n;\n    cin >> n;\n    vector<int> arr(n);\n    for(auto &it:arr)\n        cin >> it;\n    \n    cout << min_jump(arr) << \"\\n\";    \n}"
  },
  {
    "path": "Greedy or DP (Problems)/variations.txt",
    "content": "1. Find maximum no. of intervals to select with no overlap. (Jump Scheduling - I)\n--> Jump Problem (DP but like Kedans)\n\n\n2. Find minimum no. of intervals to select with minimum overlap. (Jump -II)\n--> DP solution (Job Scheduling problem)\n\n\n3. Find maximum no. of intervals which overlap at a point? (Maximum no. of train platforms problem)\n--> Use a counter variable and add 1 when an interval starts and subtract 1 when an interval ends.\n    max of counter is ans."
  },
  {
    "path": "Matrix or Backtracking(Problems)/Max_Submatrix_with_LT_Ksum.cpp",
    "content": "// Maximum size square Sub-Matrix with sum less than or equals to K\n// Link -> geeksforgeeks.org/maximum-size-square-sub-matrix-with-sum-less-than-or-equals-to-k/\n\n// Step 1: Find Prefix matrix sum[i][j] = arr[i-1][j-1]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]\n// Step 2: Iterate over all i and j (N^2)\n// Step 3: Do binary search over all possible square sizes. min(i,j);\n// Step 4: Check if square sum is less than equals to k\n\n\n// Dungeon Game  Reach n,m from 1,1 and healtmust be always +ve while moving.\n// Find starting health\n// https://leetcode.com/problems/dungeon-game/\n\n// Crux --> start from n-1,m-1 boz we need to know what will be elements next to know what to choose\n"
  },
  {
    "path": "NumberTheory/RandomNum.cpp",
    "content": "/**\n * @file RandomNum.cpp\n * @author Nisarg Gogate\n *\n * Finding random number between 0 and n-1\n * 1. rand() % n - It gives a random number but it's not evenly distributed.\n * 2. double num = rand() / RAND_MAX;\n *    num * n-1 will be truly random.\n * \n * Q. Find weighted random number index based on the weight.\n *  https://leetcode.com/problems/random-pick-with-weight/\n * As we can't really add number multiple times to array (space issue),\n * we can add it as a prefix sum. look at this prefix sum from left. we see a array same\n * as the adding number multiple times. Getting numbe in (log n) with lower_bound.\n */\n\n#include<bits/stdc++.h>\nusing namespace std;\n\nclass Solution {\npublic:\n    vector<int> prefix;\n\n    Solution(vector<int>& w) {\n        prefix.push_back(w[0]);\n        for(int i=1;i<w.size();i++) {\n            prefix.push_back(prefix.back()+w[i]);\n        }\n    }\n    \n    int pickIndex() {\n        float fraction = (float)rand()/RAND_MAX;\n        int num = fraction*prefix.back();\n\n        auto it = lower_bound(prefix.begin(), prefix.end(), num*prefix.back());\n\n        return it-prefix.begin();\n    }\n};\n"
  },
  {
    "path": "OS Concept based algos/LRU-Cache.cpp",
    "content": "// We can use stl container list as a double\n// ended queue to store the cache keys, with\n// the descending time of reference from front\n// to back and a set container to check presence\n// of a key. But to fetch the address of the key\n// in the list using find(), it takes O(N) time.\n// This can be optimized by storing a reference\n//\t (iterator) to each key in a hash map.\n\n// Refer : https : // leetcode.com/problems/lru-cache/ my solutions\n\n#include <bits/stdc++.h>\nusing namespace std;\n\nclass LRUCache\n{\n\tint capacity;\n\tlist<pair<int, int>> dq; // key, value pair\n\n\t// store references of key in cache\n\tunordered_map<int, list<pair<int, int>>::iterator> mp;\n\npublic:\n\tLRUCache(int capacity)\n\t{\n\t\tthis->capacity = capacity;\n\t}\n\n\tint get(int key)\n\t{\n\t\tif (mp.find(key) == mp.end())\n\t\t\treturn -1;\n\n\t\tint value = mp[key]->second;\n\t\tdq.erase(mp[key]);\n\t\tdq.push_front({key, value});\n\t\tmp[key] = dq.begin();\n\n\t\treturn value;\n\t}\n\n\tvoid put(int key, int value)\n\t{\n\t\tif (mp.find(key) == mp.end())\n\t\t{\n\t\t\tif (dq.size() == capacity)\n\t\t\t{\n\t\t\t\tpair<int, int> last = dq.back();\n\t\t\t\tdq.pop_back();\n\t\t\t\tmp.erase(last.first);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdq.erase(mp[key]);\n\t\t}\n\t\tdq.push_front({key, value});\n\t\tmp[key] = dq.begin();\n\t}\n};\n\n// Driver Code\nint main()\n{\n\tLRUCache ca(4);\n\n\tca.put(1, 2);\n\tca.put(2, 3);\n\tca.put(3, 2);\n\tca.put(1, 2);\n\tcout << ca.get(4) << \"\\n\";\n\tca.put(4, 1);\n\tcout << ca.get(4) << \"\\n\";\n\tca.put(5, 6);\n\treturn 0;\n}"
  },
  {
    "path": "README.md",
    "content": "# Algorithm Implementations\n\nWe have not written all of these algos ourselves. This is merely a small collection of easy and beautiful solutions to complex problems. We have added reference links and questions on top of each file for further references. Feel free to star mark and fork :D\n\n```\nCommon time complexities\n\nLet n be the main variable in the problem.\n\nIf n ≤ 12, the time complexity can be O(n!).\nIf n ≤ 25, the time complexity can be O(2n).\nIf n ≤ 100, the time complexity can be O(n4).\nIf n ≤ 500, the time complexity can be O(n3).\nIf n ≤ 104, the time complexity can be O(n2).\nIf n ≤ 106, the time complexity can be O(n log n).\nIf n ≤ 108, the time complexity can be O(n).\nIf n > 108, the time complexity can be O(log n) or O(1).\n```\n\n## Features\n- Quick access to segregated codes.\n- Easy to understand yet small solutions.\n- Tries | Segment Trees (Trees), LRU Cache (OS).\n\n## Authors\n\n- [Nisarg](https://github.com/nisarg0)\n- [Diplesh](https://github.com/dips4982)\n  \n**Special Thanks to all the youtubers for the free and awesome content!!!**\n\n- [Katik Arora](https://www.youtube.com/user/MrHulasingh25)\n- [Utkarsh Gupta](https://www.youtube.com/channel/UCGS5ZzcSAymQbWZvNoKOFhQ)\n- [take U forward](https://www.youtube.com/channel/UCJskGeByzRRSvmOyZOz61ig)\n- [Pep-coding](https://www.youtube.com/channel/UC7rNzgC2fEBVpb-q_acpsmw)\n\n    \n## Support\n\nIf you find some error do rasie issue [here](https://github.com/nisarg0/algos_implementation/issues).\n\nFor support, email nisarggogate212@gmail.com or dipleshmankape@gmail.com\n\n  \n"
  },
  {
    "path": "Range_queries/Mo's_algo.cpp",
    "content": "// Find number of elements ocuuring only once in range [L,R]."
  },
  {
    "path": "Range_queries/Persisitant tree.cpp",
    "content": ""
  },
  {
    "path": "Range_queries/Range_Update(Difference_Array).cpp",
    "content": "// Reference link -> https://www.geeksforgeeks.org/difference-array-range-update-query-o1/\n// Range update in time complexity O(1) and space complexity O(n)\n// Prefixsum and sufix sum is also a important technique but can be helpful only if \n// the operation in range is invertible(Ex add,sub or mul,div) can't be used for min,max or exor,and\n#include<bits/stdc++.h>\n\nusing namespace std;\nconst int LIM = 1e3;\nvector<int> difference(LIM,0);\n\nvoid init(int arr[],int n)\n{\n    // 0th indx is init with value of 0th element in arr\n    difference[0] = arr[0];\n    // after that nothinng should be added (precaution)\n    difference[n] = 0;\n    for(int i=1;i<n;i++)\n        difference[i] = arr[i]-arr[i-1];\n}\n// add x to all elements in between l and r (inclusive) in O(1)\nvoid update_range(int arr[], int l, int r, int n, int x)\n{\n    // invalid ip\n    if(l<0 or r >n-1 or l>r)    return;\n    // we add x to lth indx so indirectly we add x to everthing after it\n    difference[l] += x;\n    // we need to subtract x from all the elements after r\n    difference[r+1] -= x;\n}\n\nvoid print(int arr[], int n)\n{\n    arr[0] = difference[0];\n\n    for(int i=1;i<n;i++)\n        arr[i] = arr[i-1] + difference[i];\n\n    for(int i=0;i<n;i++)\n        cout<<arr[i]<<\" \";\n}\n\nint main()\n{\n    int arr[15] = { 568, 712, 412, 231, 241, 393, 865, 287, 128, 457, 238, 98, 980, 23, 782 };\n    int n = sizeof(arr)/sizeof(int);\n    int l=7,r=12;\n    // Add 5 to all elements in range l to r\n    update_range(arr,l,r,n,5);\n    print(arr,n);\n}"
  },
  {
    "path": "Range_queries/Segment_trees.cpp",
    "content": "//Segment tree for sum range-queries and updation\n/*\none-based indexing\nLIM=N\n1. Initialization   -> O(N)\n2. Range sum query  -> O(logN)    for each level we only visit not more than four vertices\n3. Update query     -> O(logN)\n*/\n\n#include<bits/stdc++.h>\n#define LIM 1007\nusing namespace std;\n\n\nint arr[LIM];           //input array\nint seg[4*LIM]={0};     //Seg tree children for index i are 2*i and 2*i+1\nint lazy[4*LIM]={0};    //lazy tree children for index i are 2*i and 2*i+1\n\n//initialization of segment tree\nvoid init_tree(int node_indx,int node_lower,int node_upper)\n{    \n    if(node_lower == node_upper)\n    {\n        seg[node_indx] = arr[node_upper];\n        return ;\n    }        \n    \n    int mid=(node_lower+node_upper)/2;\n    \n    init_tree(node_indx*2, node_lower, mid);\n    init_tree(node_indx*2+1, mid+1, node_upper);\n   \n    seg[node_indx]=seg[2*node_indx]+seg[2*node_indx+1];\n}\n\n// a,b is the range of query node_lower,node_upper is the range for particular node in seg_tree\n//a<=b and node_lower<=node_upper\nint range_query(int node_indx, int a, int b, int node_lower, int node_upper)\n{\n    //range is between a,b\n    if(a<=node_lower and node_upper<=b)   \n        return seg[node_indx];\n\n    //Not in range\n    if(b<node_lower or a>node_upper)\n        return 0;       //INT_MIN in case of min query\n\n    int mid=(node_lower+node_upper)/2;\n\n    //Intersecting on left side or right side or both  \n    return range_query(2*node_indx,a,b,node_lower,mid) +\n        range_query(2*node_indx+1,a,b,mid+1,node_upper);   \n}\n\n\n//updatepoint at a\nvoid update_point(int node_indx,int a,int node_lower, int node_upper, int val)\n{\n    if(node_upper == node_lower)\n    {\n        seg[node_indx]+=val;\n        return;\n    }\n        \n    if(a < node_lower or a>node_upper)\n        return ;\n\n    int mid=(node_lower+node_upper)/2;\n    \n    // if a is between lower and mid\n    if(node_lower >= a and a <= mid) \n        update_point(2*node_indx,a,node_lower,mid,val);\n    else\n        update_point(2*node_indx+1,a,mid+1,node_upper,val);\n\n    seg[node_indx]=seg[2*node_indx]+seg[2*node_indx+1];\n}\n\n// a,b is the range of query node_lower,node_upper is the range for particular node in seg_tree\n// change values in range[a,b] by +val\n// make a copy of seg_tree called lazy and init with 0\n\n/*void update_query(int node_indx,int a, int b, int node_lower, int node_upper, int val)\n{\n    //we need to update changes in lower levels of this node\n    if(lazy[node_indx]!=0)\n    {\n        seg[node_indx]+=(node_upper-node_lower+1)*val;\n        if(node_upper!=node_lower)\n        {\n            lazy[node_indx*2]+=lazy[node_indx];\n            lazy[node_indx*2+1]+=lazy[node_indx];\n        }\n        lazy[node_indx]=0;\n    }\n\n    //out of range\n    if(b<node_lower or a>node_upper or node_lower>node_upper ) return;\n\n    //required range is between the range of segtree\n    if(node_lower<=a and node_upper<=b)\n    {\n        seg[node_indx]+=(node_upper-node_lower+1)*val;\n        if(node_lower!=node_upper)\n        {\n            lazy[node_indx*2]+=lazy[node_indx];\n            lazy[node_indx*2+1]+=lazy[node_indx];\n        }\n        return;\n    }\n\n    //Intersecting on left side or right side or both\n    int mid=(node_lower+node_upper)/2;\n    update_query(2*node_indx,a,b,node_lower,mid,val);\n    update_query(2*node_indx+1,a,b,mid+1,node_upper,val);\n\n    seg[node_indx]=seg[node_indx*2]+seg[node_indx*2+1];\n}*/\n\n\nint main()\n{\n    int i;\n    //Intializing an array of size 10 with index itself\n    //NOTE: We have used 1 based indexing\n    for(i=1;i<=10;i++)\n    {\n        arr[i]=i;\n    }\n   \n    //Initilize the Seg tree\n    init_tree(1,1,10);\n    \n    //Range query[a,b]\n    int a,b,val;\n    cout<<\"SUM: Enter range a,b: \";\n    cin>>a>>b;\n    cout<<range_query(1,a,b,1,10)<<endl;\n    \n\n\n    //Update query[a,b] with +val\n    cout<<\"Update: Enter range a,b : \";\n    cin>>a>>b;\n    cout<<endl<<\"Update: Enter val : \";\n    cin>>val;\n    for(i=a;i<=b;i++)\n    {\n        update_point(1,i,1,10,val);\n    }\n\n    //Range query[a,b]\n    cout<<\"SUM: Enter range a,b: \";\n    cin>>a>>b;\n    cout<<range_query(1,a,b,1,10)<<endl;\n    \n}"
  },
  {
    "path": "Range_queries/sparce_table.cpp",
    "content": "// Reference -> https://www.youtube.com/watch?v=2EpX9LkO2T0\n// Refernece -> https://youtu.be/0jWeUdxrGm4\n// NOTE : We can't update efficiently\n// Precomutation- O(NLogN) Query - O(LogN)\n// If query Function asked is Idempotent(F(a,a)=a) we can solve 1 query in O(1*op). op is time taken by the operator(gcd takes more time) \n// ex. max(a,a)=a , min, gcd, bitwie-or, bitwise-and, etc.\n\n#include<bits/stdc++.h>\nusing namespace std;\n\n// #define int long long \n\nconst int LIM = (int)1e7;\nconst int K = (int)(25);\n\n\n// jth column in ith row represents the value of function from i to i+2^j.\n// st[i][j] = f(i to i+2^j)\nint st[LIM][K+1];    //30 = log2 LIM\n\nint f(int a, int b)\n{\n    return min(a,b);\n}\n\n// range [i,i+2^j−1] of length 2^j splits nicely into \n// the ranges [i,i+2^(j−1)−1] and [i+2^(j−1),i+2^(j−1)], both of length  2^(j−1).\nvoid init(int arr[],int n)\n{\n    // length of ruery is 1\n    for (int i = 0; i < n; i++)\n        st[i][0] = arr[i];\n\n    // j length query and strts from i\n    for (int j = 1; j <= K; j++)\n        for (int i = 0; i + (1 << (j-1)) <= n; i++)     // Note : the loop termination condn.\n            st[i][j] = f(st[i][j-1], st[i + (1 << (j - 1))][j - 1]);\n}\n\nint query_normal(int l,int r)\n{\n    int ans = INT_MAX;\n    // from 2^30m till 2^0 whch are the numbers we can subtract from r-l+1 till its not 0\n    // we basically add values of set bits from st.\n    for(int i=K;i>=0;i--)\n    {\n        if((1<<i) <= r-l+1)\n        {\n            ans = min(ans,st[l][i]);\n            l += 1<<i;\n        }\n    }\n    return ans;\n}\n// We are taking advantage that we don't need to keep intervals disjoint. (Intervals me overlap)\n// we can split the range [1,6] into the ranges [1,4] and [3,6]\n// Both in power of 2 (we used data from [3,4] again) So must be idempotent\nint query_idempotent(int l, int r)\n{\n    // j denotes the lenth of interval\n    int j = log2(r-l+1);\n    // r - 2^j + 1  the start indx of next range of length j.\n    return f(st[l][j], st[r-(1<<j)+1][j]);;\n}\n\nint main(void)\n{\n    int arr[15] = { 568, 712, 412, 231, 241, 393, 865, 287, 128, 457, 238, 98, 980, 23, 782 };\n    int n = sizeof(arr)/sizeof(int);\n    init(arr,n);\n\n    cout<<\"Minimum number in O(NLogN) in range: \"<<query_normal(2,3)<<endl;\n    cout<<\"Minimum number in O(1) in range: \"<<query_idempotent(2,3)<<endl;\n    return 0;\n}"
  },
  {
    "path": "Range_queries/sqrt_decomposition.cpp",
    "content": ""
  },
  {
    "path": "Range_queries/which_to_use_when.txt",
    "content": "If we need to make range update Seg_tree will most likely work\n\n"
  },
  {
    "path": "Sorting Algorithms/HeapSort.cpp",
    "content": "// Given an array implementation of Complete Binary Tree\n// Heapify function takes O(logn) \n// n is the size of array.\n#include<bits/stdc++.h>\n\nusing namespace std;\n\n// Generates heap from ith node and it's children.\nvoid heapify(vector<int> &arr, int n, int i)\n{\n    int largest = i; // Initialize largest as root\n    int l = 2 * i + 1; // left = 2*i + 1\n    int r = 2 * i + 2; // right = 2*i + 2\n \n    // If left child is larger than root\n    if (l < n && arr[l] > arr[largest])\n        largest = l;\n \n    // If right child is larger than largest so far\n    if (r < n && arr[r] > arr[largest])\n        largest = r;\n \n    // If largest is not root\n    if (largest != i) {\n        swap(arr[i], arr[largest]);\n \n        // Recursively heapify the affected sub-tree\n        heapify(arr, n, largest);\n    }\n}\n \n// main function to do heap sort\nvoid heapSort(vector<int> &arr, int n)\n{\n    // Build heap (rearrange array) \n    // We did this from n/2-1 -> 0 b'coz for a complete binary tree last n/2 elements are leave nodes.\n    for (int i = n / 2 - 1; i >= 0; i--)\n        heapify(arr, n, i);\n\n    // Now arr is a max heap\n    // Pass by ref\n\n    // One by one extract an element from heap\n    for (int i = n - 1; i > 0; i--) {\n        // Move current root to end\n        swap(arr[0], arr[i]);\n \n        // call max heapify on the reduced heap\n        heapify(arr, i, 0);\n    }\n}\n\nvoid print(vector<int> arr){\n    cout <<  \"Sorted Array is : \";\n    for(int i=0;i<arr.size();i++)\n        cout << arr[i] <<\" \";\n    cout << endl;\n}\n\nint main(){\n    int n = 5;\n    vector<int> arr{10,3,2,5,7};\n\n    heapSort(arr,n);\n\n    print(arr);\n}\n"
  },
  {
    "path": "Sorting Algorithms/Inbuilt_sorting_algos.cpp",
    "content": "#include<bits/stdc++.h>\n\nusing namespace std;\n\n// Keep variables static to avoid some error\nbool compare(int a, int b){\n    return a<b; // Just write down the condn you want to satisfy\n}\n\nint main(){\n    int n = 5;\n    int arr[n] = {10,3,2,5,7};\n\n    // Uses Intro sort\n    // n < 16               -->  Insertion Sort\n    // 16 < n < 2log(n)     -->  Quick Sort\n    // 2log(n) < n          -->  Merge Sort\n    sort(arr,arr+n);\n\n    // Decreasing sort\n    sort(arr,arr+n,greater<>());\n    // Alternate and better\n    // sort(arr+n,arr);\n\n    // Sort using comparator \n    sort(arr,arr+n,compare);\n\n    // Stable sorting using merge sort\n    // O(n*log^2(n)) if memory is not availabe else O(nlog(n))\n    stable_sort(arr,arr+n);\n\n    for(int i=0;i<n;i++)    \n        cout << arr[i] << \" \";\n}"
  },
  {
    "path": "Sorting Algorithms/MergeSort.cpp",
    "content": "// Merge Sort O(nlog(n)) with O(n) space\n// else O(nlog^2(n)) with O(1) space\n\n#include<bits/stdc++.h>\n\nusing namespace std;\n// Merges 2 arrays [lo,mid], [mid+1,hi]\nvoid merge(vector<int> &arr,int lo, int hi, int mid){\n    int i = lo,j = mid+1;\n    vector<int> ans;\n\n    while(i <= mid or j <= hi){\n        int l = i > mid ? INT_MAX : arr[i];  // is not in range take INT_MAX\n        int r = j > hi ? INT_MAX : arr[j];\n\n        if(l<r)\n            ans.push_back(l),i++;\n        else\n            ans.push_back(r),j++;\n    }\n    for(i=0;i<ans.size();i++)\n        arr[lo+i] = ans[i];\n}\n\n// We merge sorted array so call Merge Sort first then merge\nvoid mergeSort(vector<int> &arr, int lo, int hi) {\n    if(lo>=hi)\n        return;\n    \n    int mid = (lo+hi)/2;\n    mergeSort(arr,lo,mid);\n    mergeSort(arr,mid+1,hi);\n\n    merge(arr,lo,hi,mid);\n}\n\nvoid print(vector<int> arr){\n    cout <<  \"Sorted Array is : \";\n    for(int i=0;i<arr.size();i++)\n        cout << arr[i] <<\" \";\n    cout << endl;\n}\n\nint main(){\n    int n = 10,i;\n    vector<int> arr = {3,6,1,2,10,7,8,5,9,0};\n\n    mergeSort(arr,0,n-1);\n    print(arr);\n}"
  },
  {
    "path": "Sorting Algorithms/O(n^2)_Algos.cpp",
    "content": "#include<bits/stdc++.h>\nusing namespace std;\n\n// Insertion Sort\n// We divide an array into 2 parts one is sorted and other is original array\n// Size of first part keeps on increasing by 1 in each iteration and min value is put there\nvoid insertionSort(vector<int> &arr){\n    int n=arr.size(),i,j;\n    for(i=0;i<n;i++){\n        int min_val = arr[i];\n        int min_val_indx = i;\n        for(j=i+1;j<n;j++){\n            if(arr[j] < min_val){\n                min_val = arr[j];\n                min_val_indx = j;\n            }\n        }\n        swap(arr[i],arr[min_val_indx]);\n    }\n}\n\n// Selection Sort\n// Select 2 indices i,j where i<j.\n// If arr[i] > arr[j] swap them.\nvoid selectionSort(vector<int> &arr){\n    int n=arr.size(),i,j;\n    for(i=0;i<n;i++)\n        for(j=i+1;j<n;j++)\n            if(arr[i]> arr[j])\n                swap(arr[i],arr[j]);\n}\n\n// Bubble Sort\n// Like a bubble move largest element to top\n// keep on swapping adjacent elements\nvoid bubbleSort(vector<int> &arr){\n    int n = arr.size(),i,j;\n    for(i=0;i<n;i++)\n        for(j=0;j<n-i-1;j++)\n            if(arr[j] > arr[j+1])\n                swap(arr[j],arr[j+1]);\n}\n\n// Stops the comparison when the array is sorted\nvoid modified_bubbleSort(vector<int> &arr){\n    int i,j,n=arr.size();\n    bool isSorted = false;\n    for(i=0;i<n and !isSorted;i++){\n        isSorted = true;\n        for(j=0;j<n-i-1;j++){\n            if(arr[j] > arr[j+1]){\n                isSorted = false;\n                swap(arr[j],arr[j+1]);\n            }\n        }\n    }\n}\n\nvoid print(vector<int> arr){\n    cout <<  \"Sorted Array is : \";\n    for(int i=0;i<arr.size();i++)\n        cout << arr[i] <<\" \";\n    cout << endl;\n}\n\nint main(){\n    int n = 10,i;\n    vector<int> arr = {3,6,1,2,10,7,8,5,9,0};\n\n    // bubbleSort(arr);\n    // modified_bubbleSort(arr);\n    insertionSort(arr);\n    // selectionSort(arr);\n    print(arr);\n}"
  },
  {
    "path": "Sorting Algorithms/QuickSort.cpp",
    "content": "// O(nlog(n))  --> average time Complexcity \n// O(n^2)      --> worst case (If 1st element is chosen as pivot and arr is sorted)\n// O(1)        --> Extra Space \n// Link --> https://www.hackerearth.com/practice/algorithms/sorting/quick-sort/tutorial/\n// Link --> https://www.youtube.com/watch?v=if40LxQ8_Xo&t=1171s\n\n#include<bits/stdc++.h>\nusing namespace std;\n// All ements to the left of pivot are less than pivot and to the right are greater\n// It means the element is in its sorted position\nint partition(vector<int> &arr, int lo, int hi){\n    int j,i = lo+1;\n    int pivot = arr[lo];  // We try to find index of pivot\n/*\n    arr[lo] is our pivot\n    Our array lo to hi is divided into 3 regions:\n    [lo+1,j-1]      -->     Less than Pivot\n    [j,i-1]         -->     More than Pivot\n    [i,hi]          -->     Unchecked\n*/\n    \n    for(j=lo+1;j<=hi;j++){\n        if(arr[j] < pivot){\n            swap(arr[i],arr[j]);\n            i++;\n        }\n    }\n    // i-1 is largest index with no. less than pivot \n    // So it is pivot index\n    swap(arr[lo],arr[i-1]);\n    return i-1;\n}\n\n// Divide and Conquer Algo\nvoid quickSort(vector<int> &arr, int lo, int hi){\n    if(lo>=hi)\n        return;\n    int pivot_index = partition(arr,lo,hi);\n    quickSort(arr,lo,pivot_index-1);\n    quickSort(arr,pivot_index+1,hi);\n}\n\nvoid print(vector<int> arr){\n    cout <<  \"Sorted Array is : \";\n    for(int i=0;i<arr.size();i++)\n        cout << arr[i] <<\" \";\n    cout << endl;\n}\n\nint main(){\n    int n = 10;\n    vector<int> arr = {3,6,1,2,10,7,8,5,9,0};\n\n    quickSort(arr,0,n-1);\n    print(arr);\n}"
  },
  {
    "path": "Sorting Algorithms/RadixSort.cpp",
    "content": "#include<bits/stdc++.h>\nusing namespace std;\n\n// Time Complexcity = O(d*n) \n// where d is max no. of digits in a number and n is size of ar\n// Ref -> https://www.youtube.com/watch?v=a5e7RgCdel0\n\n// Question -> Max Gap Leetcode\n// We use pegion hole principle + Radix Sort to get ans in O(n) time.\n\n// elements inside a bucket = (max_val-min_val)/n-1;\n// Note bucket index (freq_index here) can be caluclated as (arr[i]-min)/interval\nvoid countSort(vector<int>& arr, int exp) {\n    vector<int> freq(10,0);\n    vector<int> ans(arr.size());\n\n    for(int i=0;i<arr.size();i++)\n        freq[(arr[i]/exp) %10]++;         // arr[i]/100 %10 gives ele at 1000th place\n    \n    vector<int> prefix_index(10,0);\n    for(int i=0;i<10;i++){\n        prefix_index[i] = freq[i];\n        if(i != 0)\n            prefix_index[i] += prefix_index[i-1];\n    }\n\n    // To convert this prefix arr to index arr\n    // Each value in prefix[i] represnts max index of i  \n    for(int i=0;i<freq.size();i++)\n        prefix_index[i]--;                                                 \n\n    // We traverse in reverse as we want to keep Radix sort stable \n    for(int i=arr.size()-1;i>=0;i--){\n        int index = (arr[i]/exp)%10;\n        ans[prefix_index[index]] = arr[i]; \n        prefix_index[index]--;\n    }\n\n    arr = ans;\n}\n\n// Works for +ve elements\nvoid radixSort(vector<int> &arr){\n    int i,max_val = INT_MIN;\n    for(i=0;i<arr.size();i++)\n        max_val = max(max_val,arr[i]);\n\n    int exp = 1;\n    // Loop till the msb of max_val\n    while(exp <= max_val) {\n        // apply count sort on (exp)'s place\n        countSort(arr,exp);\n        exp *= 10;\n    }\n}\n\nvoid print(vector<int> arr){\n    cout <<  \"\\nSorted Array is : \";\n    for(int i=0;i<arr.size();i++)\n        cout << arr[i] <<\" \";\n    cout << endl;\n}\n\nint main(){\n    int n = 10;\n    vector<int> arr = {4533,6534,5881,2896,104,7435,8236,7865,909,6450};\n\n    radixSort(arr);\n    print(arr);\n}\n"
  },
  {
    "path": "Sorting Algorithms/cycleSort.cpp",
    "content": "// Given array of size n has elements from 0 to n-1.\n// Sorting can be done in O(n) using cycleSort\n#include<bits/stdc++.h>\n\nusing namespace std;\n\nvoid cycleSort(vector<int>& arr, int n) {\n    int i = 0;\n\n    while(i<n) {\n        if(arr[i] != arr[arr[i]]) \n            swap(arr[i], arr[arr[i]]);\n        else\n            i++; // Move to next ele after the element in ith index is i\n    }\n}\n\nvoid print(vector<int> arr){\n    cout <<  \"Sorted Array is : \";\n    for(int i=0;i<arr.size();i++)\n        cout << arr[i] <<\" \";\n    cout << endl;\n}\n\nint main(){\n    int n = 5;\n    vector<int> arr{2,3,4,1,0};\n\n    cycleSort(arr,n);\n\n    print(arr);\n}"
  },
  {
    "path": "Strings/KMP.cpp",
    "content": "// String comapre Algo with O(m+n) m,n being lenghts of string to compare\n\n/* \n* IDEA - Is prefix of pattern again apperaring somewhere again in the pattern. \n* Ref Link --> https://www.youtube.com/watch?v=V5-7GzOfADQ\n*/\n\n/*\n* Indices : 0 1 2 3 4 5 6 7 8 9\n* Pattern : a b c d a b e a b c\n* Lps     : - - -   1 2   1 2 3     Rest all the values are 0\n\n* Each index in lps represents the index the pointer has to move once once the char in text doesn't match with char in pattern\n*/\n\n#include<bits/stdc++.h>\n\nusing namespace std;\n\n// pietable\n// Longest proper Prefix which is also Suffix\nvoid computeLPSArray(char* pat, int M, int* lps)\n{\n\t// length of the previous longest prefix suffix\n\tint len = 0;\n\n\tlps[0] = 0; // lps[0] is always 0\n\n\t// the loop calculates lps[i] for i = 1 to M-1\n\tint i = 1;\n\twhile (i < M) {\n\t\tif (pat[i] == pat[len]) {\n\t\t\tlen++;\n\t\t\tlps[i] = len;\n\t\t\ti++;\n\t\t}\n\t\telse // (pat[i] != pat[len])\n\t\t{\n\t\t\t// This is tricky. Consider the example.\n\t\t\t// AAACAAAA and i = 7. The idea is similar\n\t\t\t// to search step.\n\t\t\tif (len != 0) {\n\t\t\t\tlen = lps[len - 1];\n\n\t\t\t\t// Also, note that we do not increment\n\t\t\t\t// i here\n\t\t\t}\n\t\t\telse // if (len == 0)\n\t\t\t{\n\t\t\t\tlps[i] = 0;\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n// Prints occurrences of txt[] in pat[]\nvector<int> KMPSearch(char* pat, char* txt)\n{\n    vector<int> ans;\n\tint M = strlen(pat);\n\tint N = strlen(txt);\n\n\t// create lps[] that will hold the longest prefix suffix\n\t// values for pattern\n\tint lps[M];\n\n\t// Preprocess the pattern (calculate lps[] array)\n\tcomputeLPSArray(pat, M, lps);\n\n\tint i = 0; // index for txt[]\n\tint j = 0; // index for pat[]\n\twhile (i < N) {\n\t\tif (pat[j] == txt[i]) {\n\t\t\tj++;\n\t\t\ti++;\n\t\t}\n\n\t\tif (j == M) {\n\t\t\tans.push_back(i-j);\n\t\t\tj = lps[j - 1];\n\t\t}\n\n\t\t// mismatch after j matches\n\t\telse if (i < N && pat[j] != txt[i]) {\n\t\t\t// Do not match lps[0..lps[j-1]] characters,\n\t\t\t// they will match anyway\n\t\t\tif (j != 0)\n\t\t\t\tj = lps[j - 1];\n\t\t\telse\n\t\t\t\ti = i + 1;\n\t\t}\n\t}\n    return ans;\n}\n\n\n\nint main(){\n    // 0 based indexing\n    char txt[] = \"ABABDABACDABABCABAB\";\n\tchar pat[] = \"ABABCABAB\";\n\tvector<int> matched_indx = KMPSearch(pat, txt);\n    \n    cout << \"pattern appears from following indices: \";\n    for(auto indx : matched_indx)\n        cout << indx << \" \";\n}"
  },
  {
    "path": "Strings/PatternMatching.cpp",
    "content": "// Given a large text and a pattern where text >> pattern.\n// Find indices for the matching pattern in the text.\n\n// Rolling hash method: O(n) time, O(1) space\n\n/**\n * @brief Rolling hash method\n * hash(pattern) = \n * hash(pattern[0..m-1]) = (pattern[0]*d^(m-1) + pattern[1]*d^(m-2) + ... + pattern[m-1]) mod q\n * Also, First character of the pattern is the most significant character hence it's mutiplied by d^(m-1)\n * \n * \n * Formula for Rehashing text in O(1) operation given hash of previous window:\n * hash( txt[s+1 .. s+m] ) = ( d ( hash( txt[s .. s+m-1]) – txt[s]*h ) + txt[s + m] ) mod q\n * \n * NOTE: \n * d: Number of characters in the alphabet \n * q: A prime number \n * h: d^(m-1) mod q\n */\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n\nusing namespace std;\n\nint findModuloPower(int a, int b, int q) {\n    int result = 1;\n    while( b > 0) {\n        if (b & 1) {\n            result = (result * a) % q;\n        }\n        b = b >> 1;\n        a = (a * a) % q;\n    }\n    return result%q;\n}\n\n// Find hash of any string\nint findStringHash(int d, int h,int q, string str) {\n    int strHash = 0;\n    for (int i = 0; i < str.size(); i++) {\n        strHash = (d * strHash + str[i]) % q;\n    }\n    return strHash;\n}\n\n\nvector<int> findMatches(string text, string pattern) {\n    int d = 256; // Number of characters in the alphabet\n    int q = 10007; // A prime number\n\n    int n = text.size();\n    int m = pattern.size();\n\n    int h = findModuloPower(d, m-1, q);  // d^(m-1) mod q\n\n    int patternHash = findStringHash(d, h, q, pattern);\n    int textHash;\n\n    vector<int> startIndicesOfMatches;\n\n    for (int i = 0; i <= n - m; i++) {\n        // Don't need to rehash the pattern\n        if(i == 0) \n            textHash = findStringHash(d, h, q, text.substr(0, m));\n        else // Rehash the text\n            textHash = (d * (textHash - text[i - 1] * h) + text[i + m - 1]) % q;\n\n        // In case of negative hash, make it positive\n        if (textHash < 0) \n            textHash = textHash + q;\n        \n\n        if (patternHash == textHash) {\n            bool isMatch = true;\n            // In case of collision, check if the strings are actually equal\n            for (int j = 0; j < m; j++) {\n                if (text[i + j] != pattern[j]) {\n                    isMatch = false;\n                    break;\n                }\n            }\n            if (isMatch) {\n                startIndicesOfMatches.push_back(i);\n            }\n        }\n    }\n}\n\nint main() {\n    string text = \"AABAACAADAABAABA\";\n    string pattern = \"AABA\";\n\n\n    auto startIndicesOfMatches = findMatches(text, pattern);\n\n    cout << \"Indices of matches: \";\n    for (auto index : startIndicesOfMatches) {\n        cout << index << \" \";\n    }\n}\n\n\n/**\n * @brief Addition to this problem:\n * Find number of unique substring in a string\n * - Get hash for all substrings of length m (O(n*n))\n * - Store them in a set and get the size of set\n * \n * This method will mostly work as probablity of collision is approx: 1/q ie. 1/10007 = 0.0001% \n * if we increase q to 10^9 then probablity of collision will be 0.000000001%\n * \n * Read more : https://cp-algorithms.com/string/string-hashing.html#determine-the-number-of-different-substrings-in-a-string\n * \n * It can be improved by using larger q (10^18) and using a good hash function \n */"
  },
  {
    "path": "Strings/string_input.cpp",
    "content": "// If the input format of a string is know...\n// Ex.str = \"233+923i\" How to extract numbers\n\n#include<bits/stdc++.h>\nusing namespace std;\n\nint main(){\n\n    string str = \"233+923i\";\n    int a,b;\n    sscanf(str.c_str(), \"%d+%di\", &a, &b);\n    cout << a << \" \" << b << endl;\n\n//********************************* OR ***********************************\n\n    str = \"I am Nisarg and I love DS-Algo\";\n    vector<string> vec;\n\n    istringstream iss(str);\n    for(string s;iss >> s;)\n        vec.push_back(s);\n\n    for(int i=0;i<vec.size();i++)\n        cout << vec[i] << endl;\n\n\n//************************* String with spaces input ********************\n    \n    // string input;\n    // cin.ignore();\n    // getline(cin, input, '\\n');\n\n}"
  },
  {
    "path": "Trees/Binary_Lifting.cpp",
    "content": "// Note : Is apllicable only on trees\n// Precomutation : NLog(N)\n// Query output (to find LCA as well as kth ancestor) : Log(N) \n// N is basically the max height possible\n// Q. Find element kth place above x.\n// Can also be used to find LCA(Lowest Comman Ancestor) for a,b:\n\n// Demo que -->https://www.codechef.com/LTIME98B/problems/LGSEG\n// If an array is to be divided into many segments have a try if binary lifting can help somhow \n\n\n#include<bits/stdc++.h>\nconst int LIM = (int)2e5+3;\n\nusing namespace std;\n\n// elements of trees are stored from 0\nvector<int> tree[LIM];\nvector<int> parent(LIM);\nvector<int> depth(LIM);\n// up(i,j) stores element 2^j steps above (element)i. \nint up[LIM][20];\n\nvoid addEdge(int u, int v) \n{ \n    tree[u].push_back(v);\n    tree[v].push_back(u);\n}\n\n// Precomputes the up using dp.\nvoid  binary_lifting(int u, int pa)\n{\n    // up by 2^0 steps\n    up[u][0] = pa;\n\n    for(int i=1;i<20;i++)\n    {\n        if(up[u][i-1] != -1)\n            up[u][i] = up[ up[u][i-1] ][i-1];\n        else\n            up[u][i] = -1;\n    }\n\n    // Vanilla dfs\n    for(auto v: tree[u])\n        if(v != pa)\n            binary_lifting(v,u);    \n}\n\n// returns the node_val at dist h above node\n// if no node is present returns -1\nint getKthAncestor(int node, int h)\n{\n    // node should not be -1\n    for(int i=0;i<20 and node != -1;i++)\n    {\n        // if ith bit of h is set\n        if(h & 1<<i)\n            node = up[node][i];\n    }\n    return node;\n}\n\n// returns Lowest common Ancestor for nodes a,b\nint LCA(int a, int b)\n{\n    if(depth[a] < depth[b])\n        swap(a,b);\n    \n    int diff = depth[a] - depth[b];\n\n    // move a diff levels up till both a and b are not on same level\n    a = getKthAncestor(a,diff);\n\n    // imp condition\n    if(a == b)\n        return a;\n\n    // move up by 2^k steps only if on moving 2^k steps up a is not equals b.\n    for(k=19;k>=0;k--)\n    {\n        if(up[a][k] != up[b][k])\n        {\n            a = up[a][k];\n            b = up[b][k];\n        }\n    }\n\n    // we have reached one level below of LCA\n    return up[a][0];\n}\n\nint main()\n{\n    int i,src,u,v,q,x,k,V;\n\n    cout<<\"Enter number of vertices: \";\n    cin>>V;\n    \n    for(i=0;i<V-1;i++)\n    {\n        cout<<i+1<<\". Enter vertex name u and v:  \";\n        cin>>u>>v;\n        addEdge(u,v);\n    }\n   \n    src = 0;\n    binary_lifting(src,-1);\n\n    cout<<\"Enter number of queries: \";\n    cin>>q;\n    \n    for(i=0;i<q;i++)\n    {\n        cin >> x >> k;\n        cout << \"Node :\" << getKthAncestor(x,k) << \" is at a dist \" \n        << k << \"from \" << x << endl;\n    }\n}\n"
  },
  {
    "path": "Trees/LCA.cpp",
    "content": "#include<bits/stdc++.h>\nusing namespace std;\n\nclass TreeNode\n{\n    public:\n        int val;\n        TreeNode *left, *right;\n};\n\n// Assuming the given 2 nodes always exist\nTreeNode* LCA_binaryTree(TreeNode* root, int n1, int n2) {\n    if(!root)\n        return NULL;\n    if(root->val == n1 || root->val == n2)\n        return root;\n    \n    TreeNode* left_lca = LCA_binaryTree(root->left,n1,n2);\n    TreeNode* right_lca = LCA_binaryTree(root->right,n1,n2);\n\n    // if both left and right gives a ptr then root must be LCA\n    if(left_lca and right_lca)\n        return root;\n    // Left must give LCA\n    if(left_lca)\n        return left_lca;\n    else\n        return right_lca;\n}\n// For special case of BST\nTreeNode* LCA_bst(TreeNode* root, int n1, int n2) {\n    if(!root)\n        return NULL;\n    if(n1 < root->val and n2 < root->val)\n        return LCA_bst(root->left,n1,n2);\n    if(n1 > root->val and n2 > root->val)\n        return LCA_bst(root->right,n1,n2);\n    \n    // n1 < root->val and n2 > root->val\n    return root;\n}\n\n\n// -------------------------------- Helpers ---------------------\n\nTreeNode* newNode(int val)\n{\n    TreeNode* Node = new TreeNode();\n    Node->val = val;\n    Node->left = Node->right = NULL;\n    return(Node);\n}\n\nint main(){\n    TreeNode *root = newNode(20);\n    root->left = newNode(8);\n    root->right = newNode(22);\n    root->left->left = newNode(4);\n    root->left->right = newNode(12);\n    root->left->right->left = newNode(10);\n    root->left->right->right = newNode(14);\n \n    int n1 = 10, n2 = 14;\n    TreeNode *t = LCA_binaryTree(root, n1, n2);\n    cout << \"LCA of \" << n1 << \" and \" << n2 << \" is \" << t->val<<endl;\n \n    t = LCA_bst(root, n1, n2);\n    cout << \"LCA of \" << n1 << \" and \" << n2 << \" is \" << t->val<<endl;\n}"
  },
  {
    "path": "Trees/WordSearch2.cpp",
    "content": "#include<bits/stdc++.h>\nusing namespace std;\n\n// Problem Link : https://leetcode.com/problems/word-search-ii/\n// Code taken from : https://gist.github.com/SuryaPratapK/6329c354704632725dccc7ec5900d199\n\nclass Solution {    \n    struct node{    //TrieNode\n        char c;\n        int ends;\n        string word;\n        node *child[26];\n    };\n    struct node *getNode(char c)    //get newnode\n    {\n        node *newnode = new node;\n        newnode->c = c;\n        newnode->ends = 0;\n        newnode->word = \"\";\n        for(int i=0;i<26;++i)\n            newnode->child[i] = NULL;\n        return newnode;\n    }\n    node *root = getNode('/');  //root\n    \n    //Trie INSERT\n    void insert(string s)\n    {\n        node *curr=root;\n        int index,i=0;\n        while(s[i])\n        {\n            index = s[i]-'a';\n            if(curr->child[index]==NULL)\n                curr->child[index] = getNode(s[i]);\n            \n            curr=curr->child[index];\n            i+=1;\n        }\n        curr->ends += 1;\n        curr->word = s;\n    }\n    \n    void solve(vector<vector<char>>& board,int i,int j,int r,int c,vector<string>& ans,node *curr)\n    {\n        //Base case\n        //If the trie doesn't have the current char OR cell is Visited\n        int index = board[i][j]-'a';\n        if(board[i][j]=='$' || curr->child[index]==NULL)  \n            return;\n        \n        curr = curr->child[index];\n        if(curr->ends > 0)\n        {\n            ans.push_back(curr->word);\n            curr->ends -=1;\n        }\n        \n        //Body\n        char ch = board[i][j];   //Store current char\n        board[i][j] = '$';  //Mark current node visited\n        \n        if(i>0)     //TOP\n            solve(board,i-1,j,r,c,ans,curr);\n        if(i<r-1)   //DOWN\n            solve(board,i+1,j,r,c,ans,curr);\n        if(j>0)     //LEFT\n            solve(board,i,j-1,r,c,ans,curr);\n        if(j<c-1)   //RIGHT\n            solve(board,i,j+1,r,c,ans,curr);\n        \n        board[i][j] = ch;    //Mark current node as Unvisited by restoring the value\n    }\n    \npublic:\n    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {        \n        int r=board.size();\n        int c=board[0].size();\n        \n        //Insert all words in TRIE\n        for(int i=0;i<words.size();++i)\n            insert(words[i]);\n        \n        //Now search words\n        vector<string> ans;\n        for(int i=0;i<r;++i)\n        {\n            for(int j=0;j<c;++j)\n                solve(board,i,j,r,c,ans,root);\n        }\n        return ans;\n    }\n};\n"
  },
  {
    "path": "Trees/trie.cpp",
    "content": "// Reference -> https://www.geeksforgeeks.org/trie-memory-optimization-using-hash-map/\n// NOTE : \n\n#include<bits/stdc++.h>\nusing namespace std;\n\n\nconst int LIM = (int)1e7;\nconst int K = (int)(25);\n\ntypedef struct trie_tag{\n    bool isEnd;\n    map<char,trie_tag*> mp;\n\n    trie_tag(){isEnd = false;}\n}trie;\n\n// Global delecration of root pointing to null\ntrie * root = NULL;\n\nvoid insert(string str)\n{   \n    if(root == NULL)\n        root = new trie;\n\n    trie* curr = root;\n\n    for(char ch : str)\n    {\n        if(curr -> mp.find(ch) == curr -> mp.end())\n            curr -> mp[ch] = new trie;\n        // As we want to move inside that part of trie\n        curr = curr -> mp[ch];        \n    }\n    curr -> isEnd = true;\n}\n\nbool search(string str)\n{\n    trie *curr = root;\n\n    if(curr == NULL)\n        return false;\n\n    for(char ch : str)\n    {\n        if(!curr -> mp[ch])\n            return false;\n        // As we want to move inside that part of trie\n        curr = curr -> mp[ch];        \n    }\n    return curr -> isEnd;\n}\n\n// bool delete(string str)\n// {\n//     return 0;\n// }\n\nint main(void)\n{\n    vector<string> arr = {\"AABAC\",\"AAB\",\"ABC\",\"AEFDH\",\"BCD\"};\n\n    for(auto it: arr)\n        insert(it);\n    \n    if(search(\"AEFD\"))\n        cout << \"PRESENT\\n\";\n    else\n        cout << \"ABSENT\\n\";\n}"
  },
  {
    "path": "codesnippet.cpp",
    "content": "// Nisarg Gogate\n// VNIT\n\n#include<bits/stdc++.h>\n#define DEBUG_ON 0\n#define int long long \n#define TESTCASES false\n#define FASTIO true\n#define DBG(x) if(DEBUG_ON) cout << #x << \" == \" << x << endl\n#define FF first\n#define SS second\n\nconst int inf  = (int)1e18 + 1;\nconst int SIZE = (int)1e5+3;\nconst int MOD = (int)1e9+7;\nusing namespace std;\n\nint exp(int x,int n)\n{\n    int ret= 1;\n    while(n>0)\n    {\n        if(n%2)ret=(ret*x)%MOD;\n        x=(x*x)%MOD;\n        n=n/2;\n    }\n    return ret%MOD;\n}\nint inv(int x)\n{\n    return exp(x,MOD-2);\n}\n \nint ncr(int n,int r)\n{\n    if(r==0)return 1;\n    if(n<r)return 0;\n    int ret = n*ncr(n-1,r-1);\n    ret%=MOD;\n    ret*=inv(r);\n    ret%=MOD;\n    return ret;\n}\n\nint solve(int n)\n{\n    int i,j,ans=0;\n    vector<int> arr(n,0);\n    for (auto &it : arr) cin >> it;\n   \n}\n\nvoid main_code()\n{\n\tint i,j,n,k;\n    cin>>n;\n    cout<<solve(n)<<endl;\n}\n\nsigned main()\n{\n    // freopen(\"input.txt\", \"r\", stdin);\n    // freopen(\"output.txt\", \"w\", stdout);\n\t\n    if(FASTIO)\n    {\n        ios_base::sync_with_stdio(false);\n        cin.tie(NULL);\n    }\n    int T = 1;\n \n    if(TESTCASES)\n        cin >> T;\n\n    while(T--)\n        main_code();\n    \n}\n"
  }
]