社区讨论

萌新刚学 OI,为啥我的 treap TLE 了

P6136【模板】普通平衡树(数据加强版)参与者 12已保存回复 13

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@mlrm6ij9
此快照首次捕获于
2026/02/18 13:51
20 小时前
此快照最后确认于
2026/02/19 09:44
3 分钟前
查看原帖
鬼知道几年前写的代码了,TLE,原因未知。若干年后发现这题我还没补,代码比较丑陋,有无人帮忙看一眼。
CPP
#include <bits/stdc++.h>
using namespace std;
namespace my_random {
	std::chrono::high_resolution_clock::duration::rep time_nano() {
		return std::chrono::high_resolution_clock::now().time_since_epoch().count();
	}
	template<typename T = unsigned long long>
	struct xorshift {
		T seed;
		unsigned char a, b, c;
		xorshift(const T &_seed,
				 unsigned char _a = 5,
				 unsigned char _b = 11,
				 unsigned char _c = 54)
			: seed(_seed),
			  a(_a),
			  b(_b),
			  c(_c) {
			operator()();
			operator()();
			operator()();
			operator()();
		}
		xorshift(T &&_seed = time_nano(),
				 unsigned char _a = 5,
				 unsigned char _b = 11,
				 unsigned char _c = 54)
			: seed(_seed),
			  a(_a),
			  b(_b),
			  c(_c) {
			operator()();
			operator()();
			operator()();
			operator()();
		}
		const T &operator()() {
			return seed ^= (seed ^= (seed ^= seed << a) >> b) << c;
		}
	};
}
my_random::xorshift<> my_rand;
int t, x, r, cnt, last, ANS;
struct node {
    int n, l, r, s, p, f, c;
    // number, left son, right son, size, price, father, cnt
} a[1100005];
inline void read(register int &x) {
	x = 0;
    register char ch = ' ';
    while (ch < '0' || ch > '9') {
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
}
void write(register const int x) {
    if(x > 9)
        write(x / 10);
    putchar((x % 10) ^ 48);
}
inline void addsize(register int id, register const short k) {
    while (id)
    {
        a[id].s += k;
        id = a[id].f;
    }
}
inline void push_up_one_node(register const int id) {
    if (a[a[id].f].l == id) {
        register const int f = a[id].f;
        register const int g = a[f].f;
        register const int b = a[id].r;
        a[id].f = g;
        a[f].f = id;
        if (a[g].l == f) {
            a[g].l = id;
        }
        else {
            a[g].r = id;
        }
        a[id].r = f;
        a[b].f = f;
        a[f].l = b;
        a[id].s = a[f].s;
        a[f].s -= a[id].c + a[a[id].l].s;
    }
    else {
        register const int f = a[id].f;
        register const int g = a[f].f;
        register const int b = a[id].l;
        a[id].f = g;
        a[f].f = id;
        if (a[g].l == f) {
            a[g].l = id;
        }
        else {
            a[g].r = id;
        }
        a[id].l = f;
        a[b].f = f;
        a[f].r = b;
        a[id].s = a[f].s;
        a[f].s -= a[id].c + a[a[id].r].s;
    }
}
inline void push_up(register const int id) {
    while (a[id].f && a[a[id].f].p > a[id].p) {
        push_up_one_node(id);
    }
}
inline int find_rank(register int id, register int x) {
	while (1)
	{
	    if (a[id].l != 0 && x <= a[a[id].l].s) {
	        if (a[id].l == 0)
	        {
	            return a[id].n;
	        }
	    	id = a[id].l;
	    }
		else
		{
			if (x > a[id].c + a[a[id].l].s) {
				x -= a[id].c + a[a[id].l].s;
    	        if (a[id].r == 0)
    	        {
    	            return a[id].n;
    	        }
		        id = a[id].r;
		    }
		    else {
		        return a[id].n;
		    }
		}
	}
}
int get_rank(register const int id, register const int x, register const int step) {
    if (id == 0 && step) {
        return 0;
    }
    if (x == a[id].n) {
        return a[a[id].l].s;
    }
    if (x < a[id].n) {
        return get_rank(a[id].l, x, 1);
    }
    else {
        return a[a[id].l].s + a[id].c + get_rank(a[id].r, x, 1);
    }
}
int get_id(register const int id, register const int x) {
    if (x == a[id].n) {
        return id;
    }
    if (x < a[id].n) {
        if (a[id].l == 0) {
            return id;
        }
        return get_id(a[id].l, x);
    }
    else {
        if (a[id].r == 0) {
            return id;
        }
        return get_id(a[id].r, x);
    }
}
void add_node(register const int x)
{
    register const int k = get_id(0, x);
    if (a[k].n == x) {
        a[k].c++;
        addsize(k, 1);
        return;
    }
    if (a[k].n > x) {
        a[k].l = (++cnt);
        a[cnt].f = k;
        a[cnt].n = x;
        a[cnt].p = my_rand();
        addsize(cnt, 1);
        a[cnt].c++;
        push_up(cnt);
    }
    else {
        a[k].r = (++cnt);
        a[cnt].f = k;
        a[cnt].n = x;
        a[cnt].p = my_rand();
        addsize(cnt, 1);
        a[cnt].c++;
        push_up(cnt);
    }
}
void erase_node(register const int x)
{
    register const int k = get_id(0, x);
    addsize(k, -1);
    a[k].c--;
    if (a[k].c != 0) return;
    while (a[k].l != 0 || a[k].r != 0) {
        if (a[k].l != 0 && (a[k].r == 0 || a[a[k].l].p <= a[a[k].r].p)) {
            push_up_one_node(a[k].l);
        }
        else {
            push_up_one_node(a[k].r);
        }
    }
    if (a[a[k].f].l == k) {
        a[a[k].f].l = 0;
    }
    else {
        a[a[k].f].r = 0;
    }
}
void game() {
    read(t);
    read(x);
    x ^= last;
    if (t == 1) {
        add_node(x);
    }
    if (t == 2) {
        erase_node(x);
    }
    if (t == 3) {
        last = get_rank(0, x, 0) + 1;
        ANS ^= last;
    }
    if (t == 4) {
        last = find_rank(0, x);
        ANS ^= last;
    }
    if (t == 5) {
        register int id = 0, ans = 0;
        while (!ans || id) {
            if (a[id].n < x) {
                ans = max(ans, a[id].n);
                id = a[id].r;
            }
            else {
                id = a[id].l;
            }
        }
        last = ans;
        ANS ^= last;
    }
    if (t == 6) {
        register int id = 0, ans = 1000000000;
        while (!(1000000000 - ans) || id) {
            if (a[id].n > x) {
                ans = min(ans, a[id].n);
                id = a[id].l;
            }
            else {
                id = a[id].r;
            }
        }
        last = ans;
        ANS ^= last;
    }
}
signed main() {
    srand(time(0));
    a[0].n = -1;
    register int _, __;
    read(_);
    read(__);
    for (register int i = 1; i <= _; i++) {
        read(x);
    	add_node(x);
	}
    while (__--) {
        game();
    }
    write(ANS);
    return 0;
}

回复

13 条回复,欢迎继续交流。

正在加载回复...