社区讨论
KDT板子全WA求条喵
P14312【模板】K-D Tree参与者 2已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @miefja1d
- 此快照首次捕获于
- 2025/11/25 18:25 3 个月前
- 此快照最后确认于
- 2025/11/25 19:32 3 个月前
RT根本无从下手,两个样例均可通过但是全WA干净了喵
CPP// Ciallo~(∠・ω< )⌒★
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vll = vector<ll>;
#define be begin
#define ed end
#define fi first
#define se second
#define ls(p) (p << 1)
#define rs(p) (p << 1 | 1)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#ifdef LOCAL
void debug_out() { cout << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
cout << H << " ";
debug_out(T...);
}
#define debug(...) cout << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
struct KDTree {
#define int ll
static constexpr int N = 4e5 + 6;
static constexpr ll INF = 1e18;
static constexpr double alpha = 0.73;
struct Point { ll x[3]; } pt[N];
int n, idx, rt;
int buf[N], tot;
int k, m;
ll las, valbuf[N];
struct Node {
int l, r, sz;
Point p;
ll mn[3], mx[3];
ll val, sum, tag;
} tr[N];
inline int nwnode() {
if (tot) return buf[tot--];
return ++idx;
}
inline void push_up(int u) {
int l = tr[u].l, r = tr[u].r;
tr[u].sz = 1 + tr[l].sz + tr[r].sz;
tr[u].sum = tr[u].val + tr[l].sum + tr[r].sum;
for (int i = 0; i < k; i++)
tr[u].mn[i] = tr[u].mx[i] = tr[u].p.x[i];
if (l)
for (int i = 0; i < k; i++) {
tr[u].mn[i] = min(tr[u].mn[i], tr[l].mn[i]);
tr[u].mx[i] = max(tr[u].mx[i], tr[l].mx[i]);
}
if (r)
for (int i = 0; i < k; i++) {
tr[u].mn[i] = min(tr[u].mn[i], tr[r].mn[i]);
tr[u].mx[i] = max(tr[u].mx[i], tr[r].mx[i]);
}
}
inline void push_down(int u) {
if (tr[u].tag) {
int l = tr[u].l, r = tr[u].r;
if (l) {
tr[l].val += tr[u].tag;
tr[l].sum += tr[u].tag * tr[l].sz;
tr[l].tag += tr[u].tag;
}
if (r) {
tr[r].val += tr[u].tag;
tr[r].sum += tr[u].tag * tr[r].sz;
tr[r].tag += tr[u].tag;
}
tr[u].tag = 0;
}
}
int re = 0;
inline bool check(int u) {
return max(tr[tr[u].l].sz, tr[tr[u].r].sz) > alpha * tr[u].sz;
}
int flat;
inline void flatten(int u) {
if (!u) return;
push_down(u);
flatten(tr[u].l);
buf[++tot] = u;
pt[++flat] = tr[u].p;
valbuf[flat] = tr[u].val;
flatten(tr[u].r);
}
inline int choose(int l, int r) {
if (l >= r) return 0;
int dim = 0;
ll mxr = 0;
for (int d = 0; d < k; d++) {
ll mn = pt[l].x[d], mx = pt[l].x[d];
for (int i = l + 1; i <= r; i++) {
mn = min(mn, pt[i].x[d]);
mx = max(mx, pt[i].x[d]);
}
ll r = mx - mn;
if (r > mxr) {
mxr = r;
dim = d;
}
}
return dim;
}
inline int rebuild(int l, int r, int dim) {
if (l > r) return 0;
int mid = (l + r) >> 1;
nth_element(pt + l, pt + mid, pt + r + 1, [dim](const Point &a, const Point &b) {
return a.x[dim] < b.x[dim];
});
int u = nwnode();
tr[u].p = pt[mid];
tr[u].val = valbuf[mid];
tr[u].tag = 0;
int nxt_dim = (dim + 1) % k;
tr[u].l = rebuild(l, mid - 1, nxt_dim);
tr[u].r = rebuild(mid + 1, r, nxt_dim);
push_up(u);
return u;
}
inline void insert(int &u, Point p, ll val, int dim) {
if (!u) {
u = nwnode();
tr[u].p = p; tr[u].val = val;
tr[u].tag = 0; tr[u].l = tr[u].r = 0;
push_up(u);
re = sqrt(idx);
return;
}
push_down(u);
if (p.x[dim] <= tr[u].p.x[dim])
insert(tr[u].l, p, val, (dim + 1) % k);
else insert(tr[u].r, p, val, (dim + 1) % k);
push_up(u);
if (check(u)) {
flat = tot = 0;
flatten(u);
u = rebuild(1, flat, dim);
re = sqrt(idx);
}
}
inline bool chkin(const Point &p, const Point &A, const Point &B) {
for (int i = 0; i < k; i++)
if (p.x[i] < A.x[i] || p.x[i] > B.x[i])
return false;
return true;
}
inline bool chkall(int u, const Point &A, const Point &B) {
for (int i = 0; i < k; i++)
if (tr[u].mn[i] < A.x[i] || tr[u].mx[i] > B.x[i])
return false;
return true;
}
inline bool has(int u, const Point &A, const Point &B) {
for (int i = 0; i < k; i++)
if (tr[u].mx[i] < A.x[i] || tr[u].mn[i] > B.x[i])
return false;
return true;
}
inline void update(int u, const Point &A, const Point &B, ll v) {
if (!u || !has(u, A, B)) return;
push_down(u);
if (chkall(u, A, B)) {
tr[u].val += v;
tr[u].sum += v * tr[u].sz;
tr[u].tag += v;
return;
}
if (chkin(tr[u].p, A, B))
tr[u].val += v;
update(tr[u].l, A, B, v);
update(tr[u].r, A, B, v);
push_up(u);
}
inline ll query(int u, const Point &A, const Point &B) {
if (!u || !has(u, A, B)) return 0;
push_down(u);
if (chkall(u, A, B))
return tr[u].sum;
ll res = 0;
if (chkin(tr[u].p, A, B))
res += tr[u].val;
res += query(tr[u].l, A, B);
res += query(tr[u].r, A, B);
return res;
}
int test() {
cin >> k >> m;
for (int _ = 1; _ <= m; _++) {
int op; cin >> op;
if (op == 1) {
Point p;
for (int i = 0; i < k; i++) {
cin >> p.x[i];
p.x[i] ^= las;
}
ll val; cin >> val; val ^= las;
insert(rt, p, val, 0);
} else if (op == 2) {
Point A, B;
for (int i = 0; i < k; i++) {
cin >> A.x[i];
A.x[i] ^= las;
}
for (int i = 0; i < k; i++) {
cin >> B.x[i];
B.x[i] ^= las;
}
ll v; cin >> v; v ^= las;
update(rt, A, B, v);
} else {
Point A, B;
for (int i = 0; i < k; i++) {
cin >> A.x[i];
A.x[i] ^= las;
}
for (int i = 0; i < k; i++) {
cin >> B.x[i];
B.x[i] ^= las;
}
las = query(rt, A, B);
cout << las << '\n';
}
}
return 0;
}
#undef int
} s;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
s.test();
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...