子序列中任意两个相邻元素的差值不超过 k的子序列个数
给定一个长度为 n 的整数数组 nums,要求统计所有满足以下条件的子序列的个数
子序列:定义为从原数组中按顺序选取的元素组成的序列(不要求连续)。
子序列中任意两个相邻元素的差值不超过 k(即 |nums[i] - nums[j]| ≤ k)。
结果取模:由于答案可能很大,输出结果对 10^9 + 7 取模。
输入格式
第一行:整数 n 和 k(1 ≤ n ≤ 10^5,0 ≤ k ≤ 10^9)。
第二行:n 个整数,表示数组 nums(-10^9 ≤ nums[i] ≤ 10^9)。
输出格式
一个整数,表示满足条件的子序列个数。
知识点
| 函数 | 条件 | 用法 |
|---|---|---|
lower_bound |
第一个 ≥ value的位置 |
vector<int> v = {1, 3, 3, 5, 7}; |
upper_bound |
第一个 > value的位置 |
vector<int> v = {1, 3, 3, 5, 7}; |
#include <bits/stdc++.h> using namespace std; const int MOD = 1e9 + 7; class FenwickTree { public: vector<long long> tree; int size; FenwickTree(int n) { size = n; tree.resize(size + 1, 0); } void update(int i, long long val) { while (i <= size) { tree[i] = (tree[i] + val) % MOD; i += i & -i; } } long long query(int i) { long long res = 0; while (i > 0) { res = (res + tree[i]) % MOD; i -= i & -i; } return res; } long long rangeQuery(int l, int r) { return (query(r) - query(l - 1) + MOD) % MOD; } }; int countSubsequences(vector<int>& nums, int k) { int n = nums.size(); // 离散化 vector<int> sorted = nums; sort(sorted.begin(), sorted.end()); sorted.erase(unique(sorted.begin(), sorted.end()), sorted.end()); unordered_map<int, int> indexMap; for (size_t i = 0; i < sorted.size(); ++i) { indexMap[sorted[i]] = i + 1; // 从1开始编号 } FenwickTree ft(sorted.size()); long long result = 0; for (int i = 0; i < n; ++i) { int current = nums[i]; int currentIndex = indexMap[current]; // 查询范围 [current - k, current + k] 对应的离散化索引 int left = lower_bound(sorted.begin(), sorted.end(), current - k) - sorted.begin() + 1; int right = upper_bound(sorted.begin(), sorted.end(), current + k) - sorted.begin(); long long count = 1; // 当前元素本身 if (left <= right) { count = (count + ft.rangeQuery(left, right)) % MOD; } result = (result + count) % MOD; ft.update(currentIndex, count); } return result; } int main() { int n, k; cin >> n >> k; vector<int> nums(n); for (int i = 0; i < n; ++i) { cin >> nums[i]; } int result = countSubsequences(nums, k); cout << result << endl; return 0; }
浙公网安备 33010602011771号