旋转 Treap 92pts 发现引用不正确
查看原帖
旋转 Treap 92pts 发现引用不正确
331028
BlueGlassBlock楼主2022/7/11 09:32

rt, 这里是 调试 代码

#include <bits/stdc++.h>
namespace fio {
	char ch;
	template <typename T>
	inline void read(T &num) {
		num = 0;
		int f = 1;
		while (ch < '0' or ch > '9') {
			if (ch == '-') f = -1;
			ch = getchar();
		}
		while ('0' <= ch and ch <= '9') {
			num = (num << 3) + (num << 1) + (ch ^ 48);
			ch = getchar();
		}
		num *= f;
	}
	template <typename T>
	inline void write(T x) {
		if (x < 0)
			putchar('-'), x = -x;
		if (x > 9)
			write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
	template <typename T>
	inline void writel(T x) {
		write(x);
		putchar('\n');
	}
};
using namespace fio;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
enum Rotation {L, R};
const int S = 200005;
namespace Treap {
	int rt;
	struct _Node {
		int val, lson, rson, key, size, count;
	} nds[S];
	int cnt;
	int create(int x) {
		++cnt;
		nds[cnt].key = rand();
		nds[cnt].val = x;
		nds[cnt].size = 1;
		nds[cnt].count = 1;
		return cnt;
	}
	void upd_size(int rt) {
		nds[rt].size = nds[rt].count + nds[nds[rt].lson].size + nds[nds[rt].rson].size;
	}
	void rot(int &rt, Rotation dir) {
		int new_rt;
		int o_rt = rt;
		if (dir == L) {
			//   A           C
			// B   C ----> A   E
			//    D E     B D
			new_rt = nds[rt].rson;
			nds[rt].rson = nds[new_rt].lson;
			nds[new_rt].lson = rt;
		} else if (dir == R) {
			//   A           B
			// B   C ----> D   A
			//D E             E C
			new_rt = nds[rt].lson;
			nds[rt].lson = nds[new_rt].rson;
			nds[new_rt].rson = int(rt);
		}
		rt = new_rt;
		upd_size(o_rt), upd_size(new_rt);
	}
	void insert(int &rt, int val) {
		if (rt == 0) {
			rt = create(val);
			return;
		} else if (val == nds[rt].val) {
			nds[rt].count++;
		} else if (val < nds[rt].val) {
			insert(nds[rt].lson, val);
			if (nds[nds[rt].lson].key > nds[rt].key) rot(rt, R);
		} else {
			insert(nds[rt].rson, val);
			if (nds[nds[rt].rson].key > nds[rt].key) rot(rt, L);
		}
		upd_size(rt);
	}
	void remove(int &rt, int val) {
		if (!rt) return;
		if (val < nds[rt].val) {
			remove(nds[rt].lson, val);
		} else if (val > nds[rt].val) {
			remove(nds[rt].rson, val);
		} else {
			if (nds[rt].count > 1) {
				nds[rt].size--;
				nds[rt].count--;
				return;
			}
			if (nds[rt].lson or nds[rt].rson) {
				if (!nds[rt].rson or nds[nds[rt].lson].val > nds[nds[rt].rson].val) {
					rot(rt, R);
					remove(nds[rt].rson, val);
				} else {
					rot(rt, L);
					remove(nds[rt].lson, val);
				}
			} else {
				rt = 0;
				return;
			}
		}
		upd_size(rt);
	}
	int get_rank(int rt, int val) {
		int l_size = nds[nds[rt].lson].size;
		if (!rt) return 0;
		if (val == nds[rt].val) return l_size + 1;
		if (val > nds[rt].val) return get_rank(nds[rt].rson, val) + nds[rt].count + l_size;
		return get_rank(nds[rt].lson, val);
	}
	int get_val(int rt, int rank) {
		if (!rt) return INT_MAX;
		int l_size = nds[nds[rt].lson].size;
		if (rank <= l_size)
			return get_val(nds[rt].lson, rank);
		if (rank <= l_size + nds[rt].count)
			return nds[rt].val;
		return get_val(nds[rt].rson, rank - l_size - nds[rt].count);
	}
	int get_pre(int rt, int v) {
		int res = 0;
		printf("rt:%d\n", rt);
		while (rt){
			if (nds[rt].val < v) printf("LEFT res %d rt %d\n", res, rt), res = nds[rt].val, rt = nds[rt].rson;
			else rt = nds[rt].lson;
			printf("res:%d, rt:%d\n", res, rt);
		}
		return res;
	}
	int get_next(int rt, int v) {
		int res;
		while (rt){
			if (nds[rt].val > v)res = nds[rt].val, rt = nds[rt].lson;
			else rt = nds[rt].rson;
		}
		return res;
	}
	void build(){
		rt = create(-INT_MAX);
		nds[rt].rson = create(INT_MAX);
		upd_size(rt);
	}
};
int main() {
	Treap::build();
	int n;
	read(n);
	int opt, x;
	for (int i = 1; i <= n; ++i) {
		read(opt), read(x);
		switch (opt) {
		case 1:
			Treap::insert(Treap::rt, x);
			break;
		case 2:
			Treap::remove(Treap::rt, x);
			break;
		case 3:
			writel(Treap::get_rank(Treap::rt, x) - 1);
			break;
		case 4:
			writel(Treap::get_val(Treap::rt, x + 1));
			break;
		case 5:
			writel(Treap::get_pre(Treap::rt, x));
			break;
		case 6:
			writel(Treap::get_next(Treap::rt, x));
			break;
		}
	}
	
}

输入 (#11)

20
1 9508226
1 -9775935
2 9508226
2 -9775935
1 -6414629
3 -6414629
2 -6414629
1 -1847925
5 3248500
2 -1847925
1 -2757289
1 -7942063
1 -5545399
2 -7942063
1 6169408
5 -648755
1 -275474
1 -9836404
1 -3389358
1 -8467606

本地输出

1
rt:2
res:0, rt:6
LEFT res 0 rt 6
res:-1847925, rt:0
-1847925
rt:9
LEFT res 0 rt 9
res:-5545399, rt:10
res:-5545399, rt:7
LEFT res -5545399 rt 7
res:-2757289, rt:0
-2757289

在线 IDE 输出

1
rt:1
LEFT res 0 rt 1
res:-2147483647, rt:2
res:-2147483647, rt:6
LEFT res -2147483647 rt 6
res:-1847925, rt:0
-1847925
rt:1
LEFT res 0 rt 1
res:-2147483647, rt:10
res:-2147483647, rt:0
-2147483647

明显可以发现 rt 的值不同,但是我的代码确实传入了引用。。。

2022/7/11 09:32
加载中...