RainX_69

output the kth smallest number in sub-array between l and r.

Jan 12th, 2023
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.65 KB | Source Code | 0 0
  1. https://practice.geeksforgeeks.org/problems/easy-query3301/1?page=1&category[]=Segment-Tree&sortBy=submissions
  2.  
  3. You are given an array nums of size n and q queries. Now for each query of the form l, r and k, output the kth smallest number in sub-array between l and r.
  4.  
  5. Example 1:
  6. Input: nums = {4, 1, 2, 2, 3},
  7. Query = {{1, 5, 2}, {3, 5, 3}}
  8. Output: {2, 3}
  9. Explanation: For the 1st query 2nd smallest in
  10. [1, 5] is 2. For the 2nd query 3rd smallest in
  11. [3, 5] is 3.
  12.  
  13. Example 2:
  14. Input: nums = {1, 2, 3, 4, 5},
  15. Query = {{2, 5, 1}}
  16. Output: {2}
  17. Explanation: The 1st smallest in [2, 5] is 2.
  18.  
  19. ---------------------------------------------------------------------------------------------------------------------------------------
  20. // UNOPTIMISED SOLUTION
  21.  
  22. class Solution {
  23. private:
  24.     static int const MXN=15000;
  25.     vector<int> tree[4*MXN+1];
  26.     unordered_map<int,int> ranker;
  27.     unordered_map<int,int> de_ranker;
  28. public:
  29.     vector<int> Rankify(vector<int> &nums){
  30.         vector<int> temp=nums;
  31.         sort(temp.begin(),temp.end());
  32.         for(int i=0;i<nums.size();i++){
  33.             if(ranker.find(temp[i])==ranker.end()){
  34.                 ranker[temp[i]]=i;
  35.                 de_ranker[i]=temp[i];
  36.             }
  37.         }
  38.         for(int i=0;i<nums.size();i++){
  39.             temp[i]=ranker[nums[i]];
  40.         }
  41.         return temp;
  42.     }
  43.    
  44.     int De_Rankify(int index){
  45.         return de_ranker[index];
  46.     }
  47.    
  48.     vector<int> MERGE(vector<int> &arr1, vector<int> &arr2){
  49.         vector<int> res;
  50.         int n=arr1.size();
  51.         int m=arr2.size();
  52.         int i=0;
  53.         int j=0;
  54.         while(i<n && j<m){
  55.             if(arr1[i]<arr2[j]){
  56.                 res.push_back(arr1[i++]);
  57.             }
  58.             else{
  59.                 res.push_back(arr2[j++]);
  60.             }
  61.         }
  62.         while(i<n){
  63.             res.push_back(arr1[i++]);
  64.         }
  65.         while(j<m){
  66.             res.push_back(arr2[j++]);
  67.         }
  68.         return res;
  69.     }
  70.    
  71.     void buildTree(vector<int> &nums, int start, int end, int parent){
  72.         if(start>end){
  73.             return;
  74.         }
  75.         if(start==end){
  76.             tree[parent]={nums[start]};
  77.             return;
  78.         }
  79.         int mid=(start+end)/2;
  80.         buildTree(nums,start,mid,2*parent+1);
  81.         buildTree(nums,mid+1,end,2*parent+2);
  82.         vector<int> leftChild=tree[2*parent+1];
  83.         vector<int> rightChild=tree[2*parent+2];
  84.         vector<int> root=MERGE(leftChild,rightChild);
  85.         tree[parent]=root;
  86.     }
  87.    
  88.     int LessThanEle_InRange(int start, int end, int parent, int qstart, int qend, int element){
  89.         if(qstart>end || qend<start){ // no elements
  90.             return 0;
  91.         }
  92.         if(qstart<=start && qend>=end){ // count elements less than element
  93.             return upper_bound(tree[parent].begin(),tree[parent].end(),element)-tree[parent].begin();
  94.         }
  95.         int mid=(start+end)/2;
  96.         int left=LessThanEle_InRange(start,mid,2*parent+1,qstart,qend,element);
  97.         int right=LessThanEle_InRange(mid+1,end,2*parent+2,qstart,qend,element);
  98.         return left+right;
  99.     }
  100.    
  101.     bool isOK(int element, int k, int n, int l, int r){
  102.         int count=LessThanEle_InRange(0,n-1,0,l,r,element);
  103.         return count>=k;
  104.     }
  105.    
  106.     int QUERY_ANSWER(int l, int r, int k, int n){
  107.         int low=0;
  108.         int high=n-1;
  109.         int res=-1;
  110.         while(low<=high){
  111.             int mid=(low+high)/2;
  112.             if(isOK(mid,k,n,l,r)==true){ // if this mid element is the >=kth element, reduce mid
  113.                 res=mid;
  114.                 high=mid-1;
  115.             }
  116.             else{
  117.                 low=mid+1;
  118.             }
  119.         }
  120.         return De_Rankify(res);
  121.     }
  122.    
  123.     vector<int> FindQuery(vector<int> &nums, vector<vector<int>> &Query){
  124.         int n=nums.size();
  125.         vector<int> temp=Rankify(nums);
  126.         buildTree(temp,0,n-1,0);
  127.         vector<int> res;
  128.         for(auto q: Query){
  129.             int ans=QUERY_ANSWER(q[0]-1,q[1]-1,q[2],n);
  130.             res.push_back(ans);
  131.         }
  132.         return res;
  133.     }
  134. };
  135.  
  136.  
  137. ---------------------------------------------------------------------------------------------------------------------------------------
  138.  
  139. // OPTIMISED
  140.  
  141. class Solution {
  142. private:
  143.     static int const MXN=15000;
  144.     vector<int> tree[4*MXN+1];
  145. public:
  146.     vector<int> MERGE(vector<int> &arr1, vector<int> &arr2){
  147.         vector<int> res;
  148.         int n=arr1.size();
  149.         int m=arr2.size();
  150.         int i=0;
  151.         int j=0;
  152.         while(i<n && j<m){
  153.             if(arr1[i]<arr2[j]){
  154.                 res.push_back(arr1[i++]);
  155.             }
  156.             else{
  157.                 res.push_back(arr2[j++]);
  158.             }
  159.         }
  160.         while(i<n){
  161.             res.push_back(arr1[i++]);
  162.         }
  163.         while(j<m){
  164.             res.push_back(arr2[j++]);
  165.         }
  166.         return res;
  167.     }
  168.    
  169.     void buildTree(vector<pair<int,int>> &nums, int start, int end, int parent){
  170.         if(start>end){
  171.             return;
  172.         }
  173.         if(start==end){
  174.             tree[parent]={nums[start].second};
  175.             return;
  176.         }
  177.         int mid=(start+end)/2;
  178.         buildTree(nums,start,mid,2*parent+1);
  179.         buildTree(nums,mid+1,end,2*parent+2);
  180.         vector<int> leftChild=tree[2*parent+1];
  181.         vector<int> rightChild=tree[2*parent+2];
  182.         vector<int> root=MERGE(leftChild,rightChild);
  183.         tree[parent]=root;
  184.     }
  185.    
  186.     int getKthIndex(int start, int end, int parent, int qstart, int qend, int k){
  187.         if(start==end){
  188.             return tree[parent][0];
  189.         }
  190.         int mid=(start+end)/2;
  191.         int L=lower_bound(tree[2*parent+1].begin(),tree[2*parent+1].end(),qstart)-tree[2*parent+1].begin();
  192.         int R=upper_bound(tree[2*parent+1].begin(),tree[2*parent+1].end(),qend)-tree[2*parent+1].begin();
  193.         int elements=R-L;
  194.         if(elements>=k){ // if more than k elements exist in left child, move left
  195.             return getKthIndex(start,mid,2*parent+1,qstart,qend,k);
  196.         }
  197.         return getKthIndex(mid+1,end,2*parent+2,qstart,qend,k-elements);  // if less than k elements exist on left side, go right, but search for the (k-elements)th element, because, there were elements element on left side, so reduce count from side side
  198.     }
  199.    
  200.     vector<int> FindQuery(vector<int> &nums, vector<vector<int>> &Query){
  201.         int n=nums.size();
  202.         vector<pair<int,int>> a;
  203.         for(int i=0;i<n;i++){
  204.             a.push_back({nums[i],i});
  205.         }
  206.         sort(a.begin(),a.end());
  207.         buildTree(a,0,n-1,0);
  208.         vector<int> res;
  209.         for(auto q: Query){
  210.             int ans=nums[getKthIndex(0,n-1,0,q[0]-1,q[1]-1,q[2])];;
  211.             res.push_back(ans);
  212.         }
  213.         return res;
  214.     }
  215. };
  216.  
Advertisement
Add Comment
Please, Sign In to add comment