RainX_69

COUNT K LENGTH INCREASING SUBSEQUENCES

Jan 2nd, 2023 (edited)
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.97 KB | Source Code | 0 0
  1. https://www.pepcoding.com/resources/data-structures-and-algorithms-in-java-interview-prep/segment-tree/k-increasing-subsequence2-official/ojquestion
  2.  
  3. For the given sequence A with n elements find the number of strictly increasing subsequences with k elements.
  4.  
  5. Input Format
  6. First line contains two integer n and k
  7. following n lines contains elements of sequence
  8. A[1]
  9. A[2]
  10. .
  11. .
  12. A[n]
  13.  
  14. Output Format
  15. Print one number the answer to question
  16.  
  17. Constraints
  18. 1. 1 <= n <= 10^5
  19. 2. 1 <= k <= 11
  20. 3. 1 <= A[i] <= 10^9
  21. 5. A can contain duplicates
  22. 6. Output may not fit in 32 bit signed integer
  23.  
  24. Sample Input
  25. 5 2
  26. 1
  27. 1
  28. 3
  29. 8
  30. 2
  31. Sample Output
  32. 7
  33. Explaination-
  34. The 7 increasing subsequences are [1,3], [1,3], [1,8], [1,8], [1,2], [1,2], [3,8]
  35.  
  36. ---------------------------------------------------------------------------------------------------------------------------------------
  37.  
  38. BRUTE FORCE (TLE)
  39.  
  40. #include<bits/stdc++.h>
  41. using namespace std;
  42.  
  43. int main(){
  44.     int K,n;
  45.     cin>>n>>K;
  46.     vector<long long> arr(n);
  47.     for(int i=0;i<n;i++){
  48.         cin>>arr[i];
  49.     }
  50. /* ELEMENTS ARE TOO BIG, SO WE ARE ASSIGNING RANK TO THEM, WELL IF AN ARRAY IS [10,2,5], ASSIGNING THEM [3,1,2] IS THE SAME, THIS WOULD NOT AFFECT THE COUNT OF SUBSEQUENCES, SINCE YOU CAN SEE RELATIVE ORDERING IN BOTH ARE SAME, WE JUST ASSIGNED SMALLER VALUES TO THEM TO REDUCE TIME COMPLEXITY OF SEGMENT TREE */
  51.     vector<long long> temp=arr;
  52.     sort(temp.begin(),temp.end());
  53.     unordered_map<long long,long long> mpp;
  54.     long long m=1;
  55.     for(int i=0;i<n;i++){
  56.         if(mpp.find(temp[i])==mpp.end()){
  57.             mpp[temp[i]]=m;
  58.             m++;
  59.         }
  60.     }
  61.     for(int i=0;i<n;i++){
  62.         arr[i]=mpp[arr[i]];
  63.     }
  64.    
  65.     long long dp[n][K+1];
  66.     memset(dp,0,sizeof(dp));
  67.     for(int i=0;i<n;i++){
  68.         dp[i][1]=1;
  69.     }
  70.     for(int end=1;end<n;end++){
  71.         for(int start=0;start<end;start++){
  72.             if(arr[end]>arr[start]){
  73.                 for(int k=2;k<=K;k++){
  74.                          /* IT IS QUITE EASY TO IMAGINE. You are gonna add arr[end] to elements in arr[start] to achieve length k.
  75.                             Now, to achieve k length, you need to add k-1 elements. WHY? Because you are obviously adding arr[end] so
  76.                             adding 1 more, hence achieving k length in total. So, you can say, a subsequence of length 3 at arr[start]
  77.                             becomes a subsequence of length 4 at arr[end] because arr[end] gets added to it. So, in general,  
  78.                             dp[end][k]+=dp[start][k-1], for k>=2. As if k=2, at dp[end][2]+=dp[start][1], all subsequences of length
  79.                             k=1 at start will become 2 anyways when appended arr[end] to it, so we just add their count
  80.                         */
  81.                     dp[end][k]+=dp[start][k-1];
  82.                 }
  83.             }
  84.         }
  85.     }
  86.     long long res=0;
  87.     for(int i=0;i<n;i++){
  88.         res+=dp[i][K];  // ADD ALL SUBSEQUENCES WITH LENGTH K FROM EACH INDEX
  89.     }
  90.     cout<<res;  
  91.     return 0;
  92. }
  93.  
  94. --------------------------------------------------------------------------------------------------------------------------------------
  95.  
  96. SEGMENT TREE (AC)
  97.  
  98. #include<bits/stdc++.h>
  99. using namespace std;
  100.  
  101. vector<vector<long long>> tree;
  102.  
  103. vector<long long> summation(vector<long long> &left, vector<long long> &right, int k){
  104.     vector<long long> res(k+1,0);
  105.     for(int i=1;i<=k;i++){
  106.         res[i]=left[i]+right[i];
  107.     }
  108.     return res;
  109. }
  110.  
  111. vector<long long> query(int start, int end, int parent, int qstart, int qend, int k){
  112.     if(end<qstart || qend<start){
  113.         return vector<long long>(k+1,0);
  114.     }
  115.     if(qstart<=start && qend>=end){
  116.         return tree[parent];
  117.     }
  118.     int mid=(start+end)/2;
  119.     auto left=query(start,mid,2*parent+1,qstart,qend,k);
  120.     auto right=query(mid+1,end,2*parent+2,qstart,qend,k);
  121.     return summation(left,right,k);
  122. }
  123.  
  124. void update(int start, int end, int parent, int index, vector<long long> &updateThis, int k){
  125.     if(index<start || index>end){
  126.         return;
  127.     }
  128.     if(start==end){
  129.         tree[parent]=summation(updateThis,tree[parent],k);
  130.         return;
  131.     }
  132.     int mid=(start+end)/2;
  133.     if(index>mid){
  134.         update(mid+1,end,2*parent+2,index,updateThis,k);
  135.     }
  136.     else{
  137.         update(start,mid,2*parent+1,index,updateThis,k);
  138.     }
  139.     auto left=tree[2*parent+1];
  140.     auto right=tree[2*parent+2];
  141.     tree[parent]=summation(left,right,k);
  142.     return;
  143. }
  144.  
  145. int main(){
  146.     int k,n;
  147.     cin>>n>>k;
  148.     vector<int> arr(n);
  149.     for(int i=0;i<n;i++){
  150.         cin>>arr[i];
  151.     }
  152.     vector<int> temp=arr;
  153.     sort(temp.begin(),temp.end());
  154.     unordered_map<int,int> mpp;
  155.     int m=1;
  156. /* ELEMENTS ARE TOO BIG, SO WE ARE ASSIGNING RANK TO THEM, WELL IF AN ARRAY IS [10,2,5], ASSIGNING THEM [3,1,2] IS THE SAME, THIS WOULD NOT AFFECT THE COUNT OF SUBSEQUENCES, SINCE YOU CAN SEE RELATIVE ORDERING IN BOTH ARE SAME, WE JUST ASSIGNED SMALLER VALUES TO THEM TO REDUCE TIME COMPLEXITY OF SEGMENT TREE */
  157.     for(int i=0;i<n;i++){  
  158.         if(mpp.find(temp[i])==mpp.end()){
  159.             mpp[temp[i]]=m;
  160.             m++;
  161.         }
  162.     }
  163.     for(int i=0;i<n;i++){
  164.         arr[i]=mpp[arr[i]];
  165.     }
  166.     tree.resize(4*m+1,vector<long long>(k+1,0));
  167.     for(int i=0;i<n;i++){
  168.         vector<long long> Karray(k+1,0);
  169.         Karray[1]=1;
  170.         if(arr[i]!=1){ // because if arr[i]==1, we would not find arr[i]-1 that is 0 anywhere cuz every element in array has value > 0
  171.             vector<long long> KBest=query(1,m,0,1,arr[i]-1,k);
  172.            /* find the total Karray for range 1 to (arr[i]-1), as arr[i] can be appended to all elements in this range */
  173.             for(int len=2;len<=k;len++){ // same explanation, all subseq with len-1 in Kbest will be the subseq of len in Karray
  174.                 Karray[len]=KBest[len-1];
  175.             }
  176.         }
  177.         update(1,m,0,arr[i],Karray,k);
  178.     }
  179.     cout<<tree[0][k]; // this tells me the count of subseq with len k
  180.     return 0;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment