1 条题解
-
0
根据原定义,定义 阶平衡序列为长度为 的平衡序列。
显然,任何数都可以作为 阶平衡序列,其余第 阶平衡序列需要由 阶平衡序列拓展得到。
不难使用线段树判断区间最大值及其唯一性。并且,由于平衡序列的构建方法,可以发现覆盖任意特定单点的平衡序列个数为 量级。
使用
set维护每一阶平衡序列的中心位置,每次更新值时只更改可能覆盖该点的平衡序列,时间复杂度不难做到 。// #include <iostream> #include <set> #include <vector> using namespace std; const int N = 1e5 + 10, B = 17; using ll = long long; int n, a[N], rnk[N]; struct st { int mx; bool only; st operator+(const st &x) const { if (mx == x.mx) return {mx, false}; return mx > x.mx ? *this : x; } }; st tr[N << 2]; ll res; set<int> vld[B]; void build(int x = 1, int l = 0, int r = n - 1) { if (l == r) { tr[x] = {a[l], true}; rnk[l] = x; return; } int mid = (l + r) >> 1; build(x << 1, l, mid); build(x << 1 | 1, mid + 1, r); tr[x] = tr[x << 1] + tr[x << 1 | 1]; } st query(int lb, int rb, int x = 1, int l = 0, int r = n - 1) { if (l >= lb and r <= rb) return tr[x]; int mid = (l + r) >> 1; if (rb <= mid) return query(lb, rb, x << 1, l, mid); if (lb > mid) return query(lb, rb, x << 1 | 1, mid + 1, r); return query(lb, rb, x << 1, l, mid) + query(lb, rb, x << 1 | 1, mid + 1, r); } ll initialize(int N, vector<int> A) { n = N; for (int i = 0; i < n; i++) a[i] = A[i], vld[0].emplace(i), res++; build(); for (int i = 1, pv; (1 << (i + 1)) - 1 <= n; i++) { for (auto &j : vld[i - 1]) { pv = j + (1 << (i - 1)); if (pv + (1 << i) - 1 >= n) break; if (!vld[i - 1].count(pv + (1 << (i - 1)))) continue; auto buf = query(pv - (1 << i) + 1, pv + (1 << i) - 1); if (!buf.only or a[pv] != buf.mx) continue; vld[i].emplace(pv); // cerr << i << ' ' << pv << '\n'; res++; } } return res; } ll update_sequence(int p, int v) { for (int i = 1; i < B; i++) { auto it = vld[i].upper_bound(p - (1 << i)), it2 = it; while (it2 != vld[i].end() and *it2 < p + (1 << i)) it2++, res--; vld[i].erase(it, it2); } a[p] = v; tr[rnk[p]] = {v, true}; for (int i = (rnk[p] >> 1); i; i >>= 1) tr[i] = tr[i << 1] + tr[i << 1 | 1]; for (int i = 1, ivs, pv, ivs2; i < B; i++) { ivs = (1 << i) - 1 + (1 << (i - 1)); ivs2 = (1 << (i - 1)) - 1; auto it = vld[i - 1].lower_bound(p - ivs); for (; it != vld[i - 1].end() and *it <= p + ivs2; it++) { pv = *it + (1 << (i - 1)); if (pv + (1 << i) - 1 >= n) break; if (!vld[i - 1].count(pv + (1 << (i - 1)))) continue; auto buf = query(pv - (1 << i) + 1, pv + (1 << i) - 1); if (!buf.only or a[pv] != buf.mx) continue; vld[i].emplace(pv); res++; } } return res; }
- 1
信息
- ID
- 9660
- 时间
- 4000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者