Advertisement
ManZzup

Finding the Longest Increasing Subsequence using Segment Tre

Aug 1st, 2015
3,035
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.76 KB | None | 0 0
  1. /*
  2. Explained: Finding the Longest Increasing Subsequence using Segment Tree
  3. Tutorial - http://manzzup.blogspot.com/2015/08/explained-finding-longest-increasing.html
  4. */
  5. #include<iostream>
  6. #include<algorithm>
  7. #include<cmath>
  8.  
  9. using namespace std;
  10.  
  11. //define a type p just a pair
  12. typedef pair<int,int> p;
  13.  
  14. //function to compare two pairs
  15. int compare(p p1,p p2){
  16.     if(p1.first == p2.first){
  17.         //note that if the element values are equal the latter element of original array comes first
  18.         return p1.second > p2.second;
  19.     }
  20.     return p1.first < p2.first;
  21. }
  22.  
  23. //building the segment tree - more like updating the initial tree
  24. void buildTree(int* tree,int pos,int low,int high,int ind,int val){
  25.     //ind - is the original index of current element
  26.     //if ind is out of range of the current range, just stop
  27.     if(ind < low || ind > high) return;
  28.     //if low == high then the current position should be updated to the value
  29.     if(low == high){
  30.         tree[pos] = val;
  31.         return;
  32.     }
  33.    
  34.     //take the mid point
  35.     int mid = (high+low)/2;
  36.    
  37.     //recursivly call the function on the child nodes
  38.     buildTree(tree,2*pos + 1,low,mid,ind,val); 
  39.     buildTree(tree,2*pos + 2,mid+1,high,ind,val);
  40.    
  41.     //assign the current position the max of the 2 child nodes
  42.     tree[pos] = max(tree[2*pos + 1],tree[2*pos + 2]);
  43. }
  44.  
  45. //function to query the tree and find the maximum in given range upto now
  46. int findMax(int* tree,int pos,int low,int high,int st,int ed){
  47.     //uses the 3 rules of segment tree query
  48.     //if the current range is totally inside the query range return the value of current position
  49.     if(low >= st && high <= ed){
  50.         return tree[pos];
  51.     }
  52.     //if it's out of bounds, return the minimum which would be 0 in this case
  53.     if(st > high || ed < low){
  54.         return 0;
  55.     }
  56.    
  57.    
  58.     int mid = (high+low)/2;
  59.    
  60.     //else do the findMax on child nodes and return the maximum of the two
  61.     return max(findMax(tree,2*pos + 1,low,mid,st,ed),findMax(tree,2*pos + 2,mid+1,high,st,ed));
  62. }
  63.  
  64. int main(){
  65.     int ary[] = {3,1,2,8;
  66.    
  67.     int n = 4;
  68.     //generate the ary of pairs, we use pairs to store both the element and the index
  69.     p* pairs = new p[n];
  70.     for(int i=0;i<n;i++){
  71.         pairs[i].first = ary[i];
  72.         pairs[i].second = i;
  73.     }  
  74.    
  75.     //using custom sorter to sort the array
  76.     sort(pairs,pairs+n,compare);
  77.    
  78.     //the max length of segment tree is 2x(nearest power of 2 near n) - 1
  79.     int len = pow(2,(int)(ceil(sqrt(n))) + 1) - 1;
  80.     int* tree = new int[len];
  81.    
  82.     //loop all the pairs and update the tree
  83.     for(int i=0;i<n;i++){
  84.         buildTree(tree,0,0,n-1,pairs[i].second,findMax(tree,0,0,n-1,0,pairs[i].second) + 1);
  85.     }
  86.    
  87.     //print the end tree just for debug
  88.     for(int i=0;i<len;i++){
  89.         cout << tree[i] << " ";
  90.     }
  91.     cout << endl;
  92.    
  93.     //print the value of the longest subsequenc which is the root value
  94.     cout << tree[0] << endl;
  95.    
  96.    
  97.    
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement