_o_o_'s blog

By _o_o_, 3 years ago, In English

Problem : You are given an array of N integers. You have to print the total number of strictly decreasing subsequences of the array ?
Note : You cannot consider a single element to be in any strictly decreasing subsequence.(At least two elements are needed to form a strictly decreasing subsequence)

Example : Array = {15,10,20,5}
Output : 5
Explanation : The 5 strictly decreasing subsequences are {15,10}, {15,5}, {15,10,5}, {10,5}, {20,5}.

Constraints:
1≤N≤10^5
1≤Ai≤10^9 for each valid i

Motivation of the problem : I think the Subtask #1 (20 Points) of this Problem(Bunny Hops) wants us to print this only.

Awaiting for your help. Thank You !

  • Vote: I like it
  • -9
  • Vote: I do not like it

»
3 years ago, # |
  Vote: I like it +1 Vote: I do not like it

I also noticed that the Bunny Hops subtask #1 needed this. But didn't get any idea to implement that.
Though here is a GFG blog — Count all increasing subsequences(Which is almost the reverse of your query). But this only works when array elements are<10.

»
3 years ago, # |
Rev. 2   Vote: I like it +21 Vote: I do not like it

First, let's do coordinate compression on the array. That way, every number is in the range $$$[1, n]$$$.

Now, let's do DP. Let $$$dp(i)$$$ be the number of decreasing sequences (including the one with size 1) ending at position $$$i$$$. Obviously: $$$dp(i) = 1 + \displaystyle\sum_{j < i : a_j > a_i} dp(j)$$$.

But that takes quadratic time. Let's optimize it some way. Let's keep an auxiliary array cnt[], where cnt[x] is the number of strictly decreasing sequences with the last element equal to $$$x$$$.

Then, we can say that $$$dp(i) = 1 + \displaystyle\sum_{j > a_i} cnt[j]$$$. So, we can go from left to right, computing $$$dp(i)$$$ and after computing it, we update $$$cnt[]$$$ -cnt[a[i]] += dp[i].

Well, that solution is still quadratic, but we can optimize it with a data structure. Take a look at the operations that we do over the $$$cnt[]$$$ array; we are taking the sum of a suffix, and updating a single position. What well-known data structure allows us to do those operations quickly? Segment Tree, or Binary Indexed Tree (Fenwick Tree). Then, the time complexity would be $$$\mathcal{O}(n\cdot \log n)$$$.

Sample Code

struct fenwick_tree{
    
     // ...

     void add(int pos, int val){

          // this implements the operation ADD A VALUE TO A POSITION
     }

     void suffix_sum(int pos){

          // this implements the operation GET THE SUM OF A SUFFIX
     }
} DS;

ll dp[maxn];

// ...

for(int i = 1; i <= n; i++){
    dp[i] = 1 + DS.suffix_sum(a[i] + 1);
    DS.add(a[i], dp[i]);
}

Then, the total answer is $$$\displaystyle\sum_{i=1}^n (dp(i)-1)$$$, (we subtract 1 to not count sequences of length 1).

»
3 years ago, # |
  Vote: I like it +1 Vote: I do not like it

I dont think Subtask 1 is the same as the problem you are asking (it does involve counting the total number of decreasing subsequences). A simple one-liner is sufficient for subtask 1.

»
3 years ago, # |
  Vote: I like it +1 Vote: I do not like it

If you want to solve the aforementioned problem you can take the smallest decreasing subsequence that satisfies the mentioned constraints. To do this you can keep track of the maximum number encountered by you from the reverse of the array. Here's my python code for the problem.


for _ in range(int(input())): n=int(input()) # n,k=[int(i) for i in input().split(" ")] arr=[int(i) for i in input().split(" ")] mx = max(arr) mx1=max(arr[:n-1]) if mx1>arr[0] or arr[0]<arr[-1]: print(-1) else: mx = arr[-1] mxes=[] for i in range(n-1,0,-1): mx = max(arr[i],mx) mxes.append(mx) print(len(set(mxes)))