【CDQ分治】【模板】三维偏序(陌上花开)
P3810 【模板】三维偏序(陌上花开) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include <bits/stdc++.h> using namespace std; using i64 = long long; template<typename T> struct BIT { #ifndef lowbit #define lowbit(x) (x & (-x)); #endif int n; vector<T> t; BIT () {} BIT (int _n): n(_n) { t.resize(_n + 1); } BIT (int _n, vector<T>& a): n(_n) { t.resize(_n + 1); for (int i = 1; i <= n; ++ i) { t[i] += a[i]; int j = i + lowbit(i); if (j <= n) t[j] += t[i]; } } //单点修改 void update(int i, T x) { while (i <= n) { t[i] += x; i += lowbit(i); } } //区间查询 T sum(int i) { T ans = 0; while (i > 0) { ans += t[i]; i -= lowbit(i); } return ans; } T query(int i, int j) { return sum(j) - sum(i - 1); } //区间修改则存入差分数组,[l, r] + k则update(x,k),update(y+1,-k) //单点查询则直接求前缀和sum(x) //求逆序对 /* iota(d.begin(), d.end(), 0); stable_sort(d.begin(), d.end(), [&](int x, int y) { return a[x] < a[y]; });去重排序 BIT<i64> tree(n); i64 ans = 0; for (int i = 1; i <= n; i ++) { tree.update(d[i], 1); ans += i - tree.sum(d[i]); } */ }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k; vector<array<int, 3>> a(n); for (auto &[x, y, z] : a) cin >> x >> y >> z; sort(a.begin(), a.end()); vector<array<int, 5>> A; for (int i = 0; i < n; i ++) { int j = i; while (j + 1 < n && a[j + 1] == a[j]) { j ++; } A.push_back({a[j][0], a[j][1], a[j][2], j - i + 1, 0}); i = j; } BIT<i64> bit(k); auto cdq = [&](auto && self, int l, int r)->void{ if (l == r) return ; int mid = l + r >> 1; self(self, l, mid); self(self, mid + 1, r); sort(A.begin() + l, A.begin() + mid + 1, [](auto x, auto y) { if (x[1] == y[1]) return x[2] < y[2]; return x[1] < y[1]; }); sort(A.begin() + mid + 1, A.begin() + r + 1, [](auto x, auto y) { if (x[1] == y[1]) return x[2] < y[2]; return x[1] < y[1]; }); int i = l, j = mid + 1; while (j <= r) { while (i <= mid && A[i][1] <= A[j][1]) { bit.update(A[i][2], A[i][3]); i ++; } A[j][4] += bit.sum(A[j][2]); j ++; } for (int k = l; k < i; k ++) bit.update(A[k][2], -A[k][3]); }; cdq(cdq, 0, A.size() - 1); vector<i64> f(n + 1); for (auto &[a, b, c, cnt, d] : A) { f[d + cnt - 1] += cnt; } for (int i = 0; i < n; i ++) cout << f[i] << "\n"; return 0; }
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/18345928
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步