4 2 1 3 7 5
4
统计数组中的完美子序列,相邻元素差不大于d的是完美子序列。
对原数组进行排序,当前加入的数字为x,则只对接下来出现的在【x-d,x+d】范围内的数有影响。
使用线段树或树状数组统计皆可。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100005; const int base = 9901; int n, f[4 * maxn], M, d, a[maxn], b[maxn], ans; int sum(int x) { int tot = 0; for (x += M; x; x >>= 1) tot = (tot + f[x]) % base; return tot; } void add(int l, int r, int y) { for (l += M - 1, r += M + 1; l ^ r ^ 1; l >>= 1, r >>= 1) { if (~l & 1) f[l ^ 1] += y; if ( r & 1) f[r ^ 1] += y; } } int main() { while (~scanf("%d%d", &n, &d)) { for (ans = 0, M = 1; M < n; M += M); memset(f, 0, sizeof(f)); for (int i = 1; i <= n; b[i] = a[i++]) scanf("%d", &a[i]); sort(b + 1, b + n + 1); for (int i = 1; i <=n; i++) { int l = a[i] - d, r = a[i] + d, x = a[i]; l = lower_bound(b + 1, b + n + 1, l) - b; r = upper_bound(b + 1, b + n + 1, r) - b - 1; x = lower_bound(b + 1, b + n + 1, x) - b; ans += x = sum(x); ans %= base; add(l, r, x + 1); } cout << ans << endl; } return 0; }