[模板] 三维偏序 - 树套树,线段树
Posted mollnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[模板] 三维偏序 - 树套树,线段树相关的知识,希望对你有一定的参考价值。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e+7 + 5;
struct Pt {
int a, b, c;
int id;
bool operator<(const Pt &x) const { return a < x.a; }
} p[N];
map<int, int> ma, mb, mc;
int aa[N], ab[N], ac[N];
int ida, idb, idc;
int n;
int ans[N];
namespace segc {
int val[N], ch[N][2], root[N], ind;
void pushup(int p) { val[p] = val[ch[p][0]] + val[ch[p][1]]; }
void modify(int p, int l, int r, int pos) {
if (l == r) {
val[p]++;
} else {
if (pos <= (l + r) / 2) {
if (!ch[p][0])
ch[p][0] = ++ind;
modify(ch[p][0], l, (l + r) / 2, pos);
} else {
if (!ch[p][1])
ch[p][1] = ++ind;
modify(ch[p][1], (l + r) / 2 + 1, r, pos);
}
pushup(p);
}
}
void modify(int ver, int pos) {
if (!root[ver])
root[ver] = ++ind;
modify(root[ver], 1, n, pos);
}
int query(int p, int l, int r, int ql, int qr) {
if (l > qr || r < ql || p == 0)
return 0;
if (l >= ql && r <= qr)
return val[p];
return query(ch[p][0], l, (l + r) / 2, ql, qr) + query(ch[p][1], (l + r) / 2 + 1, r, ql, qr);
}
int query(int ver, int ql, int qr) { return query(root[ver], 1, n, ql, qr); }
} // namespace segc
namespace segb {
void modify(int p, int l, int r, int pos, int posi) {
segc::modify(p, posi);
if (l != r) {
if (pos <= (l + r) / 2)
segb::modify(p * 2, l, (l + r) / 2, pos, posi);
else
segb::modify(p * 2 + 1, (l + r) / 2 + 1, r, pos, posi);
}
}
void modify(int pos, int posi) { modify(1, 1, n, pos, posi); }
int query(int p, int l, int r, int ql, int qr, int iql, int iqr) {
if (l > qr || r < ql)
return 0;
if (l >= ql && r <= qr)
return segc::query(p, iql, iqr);
return query(p * 2, l, (l + r) / 2, ql, qr, iql, iqr) +
query(p * 2 + 1, (l + r) / 2 + 1, r, ql, qr, iql, iqr);
}
int query(int ql, int qr, int iql, int iqr) { return query(1, 1, n, ql, qr, iql, iqr); }
} // namespace segb
int k;
signed main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &p[i].a, &p[i].b, &p[i].c);
ma[p[i].a]++;
mb[p[i].b]++;
mc[p[i].c]++;
p[i].id = i;
}
for (map<int, int>::iterator it = ma.begin(); it != ma.end(); it++)
it->second = ++ida, aa[ida] = it->first;
for (map<int, int>::iterator it = mb.begin(); it != mb.end(); it++)
it->second = ++idb, ab[idb] = it->first;
for (map<int, int>::iterator it = mc.begin(); it != mc.end(); it++)
it->second = ++idc, ac[idc] = it->first;
for (int i = 1; i <= n; i++) {
p[i].a = ma[p[i].a];
p[i].b = mb[p[i].b];
p[i].c = mc[p[i].c];
}
sort(p + 1, p + n + 1);
for (int i = 1; i <= n;) {
int j;
for (j = i; j <= n; j++)
if (p[i].a != p[j].a)
break;
--j;
for (int k = i; k <= j; k++) segb::modify(p[k].b, p[k].c);
for (int k = i; k <= j; k++) {
ans[segb::query(1, p[k].b, 1, p[k].c)]++;
}
i = j + 1;
}
for (int i = 1; i <= n; i++) printf("%d
", ans[i]);
}
以上是关于[模板] 三维偏序 - 树套树,线段树的主要内容,如果未能解决你的问题,请参考以下文章