WBLT 92pts 求卡常。

P6136 【模板】普通平衡树(数据加强版)

TernaryTree @ 2024-01-31 10:07:12

#include <bits/stdc++.h>
//#define int long long
#define ls ch[0]
#define rs ch[1]

using namespace std;
using db = double;

struct ios {
    inline char read() {
        static const int inlen = 1 << 18 | 1;
        static char buf[inlen], *s, *t;
        return (s == t) && (t = (s = buf) + fread(buf, 1, inlen, stdin)), s == t ? -1 : *s++;
    }
    template<typename T> inline ios& operator>> (T &x) {
        static char c11, boo;
        for (c11 = read(), boo = 0; !isdigit(c11); c11 = read()) {
            if (c11 == -1) return *this;
            boo |= c11 == '-';
        }
        for (x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0');
        boo && (x = -x);
        return *this;
    }
} fin;

struct exios {
    template<typename _CharT, typename _Traits = char_traits<_CharT>>
    struct typ {
        typedef basic_ostream<_CharT, _Traits>& (* end) (basic_ostream<_CharT, _Traits>&);
    };

    template<typename T> friend exios &operator<<(exios &out, T num) {
        if (num < 0) putchar('-'), num = -num;
        if (num >= 10) out << num / 10;
        putchar(num % 10 + '0');
        return out;
    }

    friend exios &operator<<(exios &out, const char * s) { printf("%s", s); return out; }
    friend exios &operator<<(exios &out, string s) { cout << s; return out; }
    friend exios &operator<<(exios &out, typ<char>::end e) { puts(""); return out; }
} fout;

const int maxn = 2.3e6 + 10;
const db A = 1 - sqrt(2) / 2;

struct node {
    int l, r, size;
    int ch[2] = {};
};

node tr[maxn];
int root, tot, cnt;
int del[maxn];

int newnode(int x) {
    tr[++tot].l = x;
    tr[tot].r = x;
    tr[tot].size = 1;
    return tot;
}

void pushup(int u) {
    if (tr[u].ls) {
        tr[u].size = tr[tr[u].ls].size + tr[tr[u].rs].size;
        if (tr[u].size == cnt) root = u;
        tr[u].l = min(tr[tr[u].ls].l, tr[tr[u].rs].l);
        tr[u].r = max(tr[tr[u].ls].r, tr[tr[u].rs].r);
    }
}

void rotate(int u, int d) {
    int tmp = tr[u].ch[d ^ 1];
    tr[u].ch[d ^ 1] = tr[u].ch[d];
    tr[u].ch[d] = tr[tr[u].ch[d ^ 1]].ch[d];
    tr[tr[u].ch[d ^ 1]].ch[d] = tr[tr[u].ch[d ^ 1]].ch[d ^ 1];
    tr[tr[u].ch[d ^ 1]].ch[d ^ 1] = tmp;
    pushup(tr[u].ch[d ^ 1]);
    pushup(u);
}

void maintain(int u) {
    int d;
    if (tr[u].ls) {
        if (tr[tr[u].ls].size < tr[u].size * A) d = 1;
        else if (tr[tr[u].rs].size < tr[u].size * A) d = 0;
        else return;
    }
    if (tr[tr[tr[u].ch[d]].ch[d ^ 1]].size >= tr[tr[u].ch[d]].size * ((1 - A * 2) / (1 - A))) rotate(tr[u].ch[d], d ^ 1);
    else rotate(u, d);
}

void insert(int u, int x) {
    if (!cnt) return (void) (newnode(x), ++cnt, root = tot);
    if (tr[u].size == 1) {
        tr[u].ls = newnode(x);
        tr[u].rs = newnode(tr[u].l);
        ++cnt;
        if (x > tr[u].l) swap(tr[u].ls, tr[u].rs);
    } else {
        insert(tr[u].ch[x > tr[tr[u].ls].r], x);
    }
    pushup(u);
    maintain(u);
}

void delnode(int u) {
    tr[u].ls = tr[u].rs = tr[u].l = tr[u].r = tr[u].size = 0;
    del[u] = 1;
}

void remove(int u, int x) {
    if (cnt == 1) return (void) (delnode(u), --cnt, root = 0);
    int d = x > tr[tr[u].ls].r;
    if (tr[tr[u].ch[d]].size == 1) {
        if (tr[tr[u].ch[d]].l != x) return;
        delnode(tr[u].ch[d]);
        int tmp = tr[u].ch[d ^ 1];
        tr[u] = tr[tr[u].ch[d ^ 1]];
        delnode(tmp);
        cnt--;
    } else {
        remove(tr[u].ch[d], x);
    }
    pushup(u);
    maintain(u);
}

int queryrank(int u, int x) {
    if (tr[u].size == 1) return (tr[u].l < x) + 1;
    if (x > tr[tr[u].ls].r) return tr[tr[u].ls].size + queryrank(tr[u].rs, x);
    else return queryrank(tr[u].ls, x);
}

int getkth(int u, int k) {
    if (tr[u].size == 1) return tr[u].l;
    if (k <= tr[tr[u].ls].size) return getkth(tr[u].ls, k);
    else return getkth(tr[u].rs, k - tr[tr[u].ls].size);
}

int getpre(int u, int x) {
    if (tr[u].size == 1) return tr[u].l;
    if (x <= tr[tr[u].rs].l) return getpre(tr[u].ls, x);
    else return getpre(tr[u].rs, x);
}

int getsuf(int u, int x) {
    if (tr[u].size == 1) return tr[u].l;
    if (x >= tr[tr[u].ls].r) return getsuf(tr[u].rs, x);
    else return getsuf(tr[u].ls, x);
}

void debug() {
    cout << root << endl;
    for (int i = 1; i <= tot; i++) {
        cout << tr[i].ls << " " << tr[i].rs << " " << tr[i].l << " " << tr[i].r << " " << tr[i].size << " " << del[i] << endl;
    } 
}

signed main() {
    int n, m, last = 0, ans = 0;
    fin >> n >> m;
    while (n--) {
        int x;
        fin >> x;
        insert(root, x);
    }
    while (m--) {
        int op, x;
        fin >> op >> x;
        x ^= last;
        if (op == 1) insert(root, x);
        else if (op == 2) remove(root, x);
        else if (op == 3) (last = queryrank(root, x));
        else if (op == 4) (last = getkth(root, x));
        else if (op == 5) (last = getpre(root, x));
        else if (op == 6) (last = getsuf(root, x));
        if (op >= 3 && op <= 6) ans ^= last;
    }
    fout << ans << endl;
    return 0;
}

by Meardoe @ 2024-01-31 10:12:16

你咋在写网暴了树?


by TernaryTree @ 2024-01-31 10:14:18

@Meardoe ?


by call_of_silence @ 2024-01-31 10:22:09

@TernaryTree 3.2s固若磐石,时间充裕的话建议重构ing


by TernaryTree @ 2024-01-31 10:23:02

@call_of_silence 我发现是 RE,/ng。


by TernaryTree @ 2024-01-31 10:56:48

@call_of_silence 哥们,我会 fhq


by call_of_silence @ 2024-01-31 10:59:04

@TernaryTree orz,大佬加油


by TernaryTree @ 2024-01-31 11:33:55

已通过,感谢。


|