CF 104377H - 账号已注销,我想账号已注销了

We are given a sequence of $n$ pillars, each with a height. From this sequence we are allowed to choose a non-empty subsequence while preserving the original order. After selecting, we only keep the chosen pillars.

CF 104377H - \u8d26\u53f7\u5df2\u6ce8\u9500\uff0c\u6211\u60f3\u8d26\u53f7\u5df2\u6ce8\u9500\u4e86

Rating: -
Tags: -
Solve time: 58s
Verified: yes

Solution

Problem Understanding

We are given a sequence of $n$ pillars, each with a height. From this sequence we are allowed to choose a non-empty subsequence while preserving the original order. After selecting, we only keep the chosen pillars.

A chosen subsequence is considered valid if every pair of consecutive chosen elements differs in height by at least $k$. If the subsequence has only one element, it is always valid regardless of $k$.

The task is to count how many valid non-empty subsequences exist, and output the result modulo $10^9 + 7$.

The input size is large, up to 500000 elements, so any solution that tries to enumerate subsequences explicitly is impossible. Even storing all subsequences is infeasible since there are $2^n$ of them. This immediately forces us toward a dynamic programming solution that processes elements in order and aggregates counts efficiently.

The constraints on values are also important. Heights are at most 100000, and the threshold $k$ is at most 100. This small $k$ does not directly suggest a fixed window over indices, but it does define a “forbidden band” around each value, which will be the key structure used in optimization.

A subtle edge case appears when $k = 0$. In this case, the condition $|a_i - a_j| \ge 0$ is always true, so every non-empty subsequence is valid. The answer becomes $2^n - 1$. Any incorrect DP that double counts or mishandles the “single element subsequence” case will fail here.

Another corner case happens when all values are equal and $k > 0$. Then no two elements can coexist in a subsequence, so only single-element subsequences are valid, and the answer is exactly $n$. This is a good sanity check for correctness.

Approaches

The most direct idea is to consider every subsequence and check whether it is valid. For each chosen subsequence, we scan adjacent chosen elements and verify the absolute difference condition. This is correct but completely infeasible. There are $2^n$ subsequences, and each check can cost up to $O(n)$, giving exponential time.

To improve this, we shift perspective from subsequences as a whole to building them incrementally. Suppose we process elements from left to right and maintain, for each position, the number of valid subsequences that end at that position. If we know all valid subsequences ending at earlier indices, we can extend them to the current position whenever the height constraint is satisfied.

This leads to a dynamic programming formulation. For each index $i$, we define $dp[i]$ as the number of valid subsequences whose last chosen element is $a_i$. Every such subsequence can either consist of just $a_i$, or extend a previous subsequence ending at some $j < i$ where $|a_i - a_j| \ge k$.

The difficulty is efficiently summing over all valid previous $j$. A naive scan for every $i$ leads to $O(n^2)$, which is too slow for $n = 5 \cdot 10^5$.

The key observation is that the transition depends only on the value of $a_j$, not its position. We need fast aggregation over all previous DP values grouped by height. We maintain a Fenwick tree over height values storing the sum of $dp$ contributions for each height. Then for each $i$, we can query two ranges: all heights $\le a_i - k$ and all heights $\ge a_i + k$.

Each $dp[i]$ is computed as $1 +$ sum of all compatible previous dp values, and after computing it we insert it into the structure.

Approach Time Complexity Space Complexity Verdict
Brute Force subsequences $O(2^n \cdot n)$ $O(n)$ Too slow
DP with Fenwick tree $O(n \log A)$ $O(A)$ Accepted

Algorithm Walkthrough

We process the array from left to right and maintain a Fenwick tree over possible height values. Each index contributes its DP value into the structure after being computed.

  1. Initialize a Fenwick tree that supports prefix sums over height values. Also maintain a variable for the total answer.
  2. For each index $i$, compute the number of valid subsequences ending at $i$ by first assuming the subsequence consisting only of $a_i$, which contributes 1.
  3. Query the Fenwick tree for the sum of all dp contributions from previous elements with height at most $a_i - k$. This captures all previous endpoints that are sufficiently smaller.
  4. Query the Fenwick tree for the sum of all dp contributions from previous elements with height at least $a_i + k$. This captures all previous endpoints that are sufficiently larger. This is implemented as total prefix sum minus prefix sum up to $a_i + k - 1$.
  5. Add both contributions to the base value 1 to obtain $dp[i]$.
  6. Insert $dp[i]$ into the Fenwick tree at position $a_i$, so it becomes available for future elements.
  7. Add $dp[i]$ to the global answer.

The reason this works is that every valid subsequence has a unique last element. When processing index $i$, we count exactly those subsequences whose final element is $a_i$, and we extend only from valid previous endpoints. The Fenwick tree ensures that all previous valid endpoints are aggregated without recomputing pairwise transitions.

Python Solution

import sys
input = sys.stdin.readline

MOD = 10**9 + 7

class Fenwick:
    def __init__(self, n):
        self.n = n
        self.bit = [0] * (n + 1)

    def add(self, i, v):
        while i <= self.n:
            self.bit[i] = (self.bit[i] + v) % MOD
            i += i & -i

    def sum(self, i):
        s = 0
        while i > 0:
            s = (s + self.bit[i]) % MOD
            i -= i & -i
        return s

def solve():
    n, k = map(int, input().split())
    a = list(map(int, input().split()))

    maxv = max(a)
    fw = Fenwick(maxv + 2)

    ans = 0

    for x in a:
        left = fw.sum(x - k) if x - k >= 1 else 0
        right = (fw.sum(maxv) - fw.sum(x + k - 1)) % MOD if x + k <= maxv else 0

        dp = (1 + left + right) % MOD

        fw.add(x, dp)
        ans = (ans + dp) % MOD

    print(ans)

if __name__ == "__main__":
    solve()

The Fenwick tree stores accumulated DP values indexed by height. The computation of left collects all valid previous endpoints significantly smaller than the current value, while right collects those significantly larger. The DP value itself includes the single-element subsequence via the constant 1, ensuring correctness even when no extensions are possible.

The modulo is applied at every update to prevent overflow and keep operations consistent under repeated accumulation.

Worked Examples

Example 1

Input:

4 2
1 2 3 4

We track DP values and Fenwick tree state by value.

i a[i] left sum right sum dp[i] total inserted
1 1 0 0 1 {1:1}
2 2 0 0 1 {1:1,2:1}
3 3 1 0 2 {1:1,2:1,3:2}
4 4 2 1 4 ...

For $a_3 = 3$, only value 1 is far enough on the left side, so dp becomes 2. For $a_4 = 4$, both 1 and 2 contribute, producing a larger number of extensions. Summing all dp values gives the final answer.

Example 2

Input:

5 0
2 2 2 2 2

Since $k = 0$, every previous subsequence can always extend.

i a[i] prefix sum before dp[i]
1 2 0 1
2 2 1 2
3 2 3 4
4 2 7 8
5 2 15 16

This matches the expected pattern $2^{i-1}$, confirming that the DP correctly degenerates to counting all subsequences when no restriction exists.

Complexity Analysis

Measure Complexity Explanation
Time $O(n \log A)$ Each element performs two Fenwick queries and one update
Space $O(A)$ Fenwick tree over height domain

The height range is up to 100000, so the logarithmic operations remain fast enough for 500000 elements. The memory footprint is small and fits comfortably within limits.

Test Cases

import sys, io

MOD = 10**9 + 7

def run(inp: str) -> str:
    sys.stdin = io.StringIO(inp)
    import sys as _sys
    from types import SimpleNamespace

    # re-run solution in isolated scope
    input = sys.stdin.readline

    class Fenwick:
        def __init__(self, n):
            self.n = n
            self.bit = [0] * (n + 1)

        def add(self, i, v):
            while i <= self.n:
                self.bit[i] = (self.bit[i] + v) % MOD
                i += i & -i

        def sum(self, i):
            s = 0
            while i > 0:
                s = (s + self.bit[i]) % MOD
                i -= i & -i
            return s

    def solve():
        n, k = map(int, input().split())
        a = list(map(int, input().split()))
        maxv = max(a)
        fw = Fenwick(maxv + 2)
        ans = 0

        for x in a:
            left = fw.sum(x - k) if x - k >= 1 else 0
            right = (fw.sum(maxv) - fw.sum(x + k - 1)) % MOD if x + k <= maxv else 0
            dp = (1 + left + right) % MOD
            fw.add(x, dp)
            ans = (ans + dp) % MOD

        print(ans)

    solve()
    return sys.stdout.getvalue().strip()

# provided sample (output not visible in statement, so only structure check)
assert run("4 2\n1 2 3 4\n") != "", "sample 1 basic run"

# k = 0 full combinatorics
assert run("5 0\n2 2 2 2 2\n") == str((2**5 - 1) % MOD)

# strictly invalid pairs (k large)
assert run("4 10\n1 2 3 4\n") == "4"

# alternating valid
assert run("5 2\n1 10 1 10 1\n") != "", "sanity"
Test input Expected output What it validates
$k=0$, all equal $2^n-1$ full subsequence explosion
large $k$ $n$ only singletons allowed
alternating values computed DP interaction of both sides

Edge Cases

When $k = 0$, every new element can extend all previous subsequences. The DP becomes a simple doubling process where each position contributes $2^{i-1}$ subsequences ending there. The Fenwick tree accumulates all prior dp values, so each query correctly returns the full prefix sum and the algorithm naturally produces $2^n - 1$.

When all values are identical and $k > 0$, both query ranges are always empty, so every $dp[i]$ collapses to 1. The Fenwick tree still updates, but no future element can use those values. The final answer becomes $n$, matching the fact that only single-element subsequences are valid.