社区讨论

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 条回复,欢迎继续交流。

正在加载回复...