测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A29401. 漂亮的序列

填空题 较难

题目描述

漂亮的序列

题目描述

时间限制:6000    内存限制:65536

对于给定的整数 m,我们称一个序列是“漂亮”的,如果它包含至少 2 个整数,并且有 2 个相邻数字的差不超过m。你的任务是计算一个给定的 n 个正整数的序列中,有多少个子序列是漂亮的。

输入

输入第一行给出 2 个正整数 n 和 m (2 ≤ n ≤ 105, 1 ≤ m ≤ 103),随后一行给出序列中 n 个不超过 105 的正整数。同行数字间以空格分隔。

输出

输出原始序列中漂亮子序列的个数。因为答案可能非常大,所以你需要输出对 1000000007 (109 + 7) 取模后的结果。

样例输入

4 2
5 3 8 6

样例输出

8

提示

样例解释:

1、子序列下标为 {1, 2}, 对应值为 {5, 3};

2、子序列下标为 {1, 4}, 对应值为 {5, 6};

3、子序列下标为 {3, 4}, 对应值为 {8, 6};

4、子序列下标为 {1, 2, 3}, 对应值为 {5, 3, 8};

5、子序列下标为 {1, 2, 4}, 对应值为 {5, 3, 6};

6、子序列下标为 {1, 3, 4}, 对应值为 {5, 8, 6};

7、子序列下标为 {2, 3, 4}, 对应值为 {3, 8, 6};

8、子序列下标为 {1, 2, 3, 4}, 对应值为 {5, 3, 8, 6}。

参考答案

#include <bits/stdc++.h> using namespace std; const int MOD = 1000000007; class FenwickTree { private: vector<int> tree; int n; public: FenwickTree(int size) : n(size) { tree.assign(n + 2, 0); // 索引从1到n+1 } void update(int idx, int val) { idx++; // 树状数组从1开始 if (idx > n) return; // 超出范围的不处理 while (idx <= n) { tree[idx] = (tree[idx] + val) % MOD; idx += idx & -idx; } } int query(int idx) { idx++; // 转换为树状数组的索引 if (idx < 0) return 0; int res = 0; while (idx > 0) { res = (res + tree[idx]) % MOD; idx -= idx & -idx; } return res; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; } int max_a = *max_element(a.begin(), a.end()); int max_val = max_a + m; FenwickTree bit(max_val); long long sum_dp = 0; int total_sum = 0; for (int ai : a) { int left = ai - m - 1; int sum_left = bit.query(left); int right = ai + m; int sum_right = (total_sum - bit.query(right) + MOD) % MOD; int dp_i = (sum_left + sum_right + 1) % MOD; sum_dp = (sum_dp + dp_i) % MOD; bit.update(ai, dp_i); total_sum = (total_sum + dp_i) % MOD; } long long S = (sum_dp - n + MOD) % MOD; // 计算2^n mod MOD auto powmod = [](long long a, int b, int mod) { long long res = 1; while (b > 0) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; }; long long T = (powmod(2, n, MOD) - 1 - n + MOD) % MOD; long long ans = (T - S + MOD) % MOD; cout << ans << '\n'; return 0; }
上一题 下一题