普通的查找树全MLE求调
查看原帖
普通的查找树全MLE求调
759274
Stevehim楼主2022/10/22 00:35

RT...

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#define maxn 10010
using namespace std;
const long long INF = 2147483647;

//自制 二叉平衡树
struct node {
	int ls = -1;
	int rs = -1;
	int val;
	int size = 0;
	int cnt;
} x[maxn];
int bnt = 0;

void add(int v, int num = 0) { //num表示当前有值的结点的的序号,v表示添加的值
	if (bnt == 0) { //检测bnt,事实上日报恰恰少了这一步
		x[bnt].val = v;
		x[bnt].size = 1;
		x[bnt].cnt = 1;
		bnt++;
		return; //根节点创建完成,退出
	} else { //不是
		x[num].size++;
		if (x[num].val == v) { //如果值相等
			x[num].cnt++; //计数器++
			return;
		}
		if (x[num].val > v) { //如果这个节点的值大于给的值,说明需要走左边
			if (x[num].ls == -1) { //这里与日报不一样,我检测有没有子树
				x[bnt].val = v;
				x[bnt].size = 1;
				x[bnt].cnt = 1;
				x[num].ls = bnt; //建立关系
				bnt++;
			} else {
				add(v, x[num].ls); //有左子树,就下放到左边的结点
			}
		} else { //如果这个节点的值小于给的值,走右边
			if (x[num].rs == -1) { //这里与日报不一样,我检测有没有子树
				x[bnt].val = v;
				x[bnt].size = 1;
				x[bnt].cnt = 1;
				x[num].rs = bnt; //建立关系
				bnt++;
			} else {
				add(v, x[num].rs); //有左子树,就下放到左边的结点
			}
		}
	}
}

int GetPre(int num, int v, int ans) { //num表示将要进行比较的结点,v表示需要查找的,ans表示备份的答案
	if (x[num].val >= v) {
		if (x[num].ls == -1) {
			return ans; //返回答案备份
		} else {
			return GetPre(x[num].ls, v, ans);
		}
	} else {
		if (x[num].rs == -1) {
			return x[num].val;
		} else {
			return GetPre(x[num].rs, v, x[num].val);
		}
	}
}

int GetNext(int num, int v, int ans) { //num表示将要进行比较的结点,v表示需要查找的,ans表示备份的答案
	if (x[num].val <= v) {
		if (x[num].rs == -1) {
			return ans; //返回答案备份
		} else {
			return GetNext(x[num].rs, v, ans);
		}
	} else {
		if (x[num].ls == -1) {
			return x[num].val;
		} else {
			return GetNext(x[num].ls, v, x[num].val);
		}
	}
}

int root_size = x[0].size - x[x[0].rs].size;

int GetValByRank(int num, int rank) { //num指当前比较的结点,rank指排名
	if (rank == 0) {
		return INF;
	}
	if (rank == root_size) {
		return x[0].val;
	}
	if (x[x[num].ls].size >= rank) { //先查看普遍值偏小的子树的大小是否足够排名了
		return GetValByRank(x[num].ls, rank); //跑到左子树的左子树里面查
	}
	if (x[x[num].ls].size + x[num].cnt >= rank) { //左子树与我当前这个结点有的个数的值加起来大于它
		return x[num].val; //直接返回吧
	}
	return GetValByRank(x[num].rs, rank - x[x[num].ls].size - x[num].cnt);
}

int GetRankByVal(int num, int val) { //变量意义参上
	if (val == x[num].val) {
		return x[x[num].ls].size + 1;
	}
	if (val < x[num].val) {
		return GetRankByVal(x[num].ls, val);
	}
	return GetRankByVal(x[num].rs, val) + x[x[num].ls].size + x[num].cnt;
}


int q, opt, x1;

int main() {
	cin >> q;
	for (int i = 0; i < q; i++) {
		cin >> opt >> x1;
		switch (opt) {
			case 1: {
				cout << GetRankByVal(0, x1) << endl;
				break;
			}
			case 2: {
				cout << GetValByRank(0, x1) << endl;
				break;
			}
			case 3: {
				cout << GetPre(0, x1, -INF) << endl;
				break;
			}
			case 4: {
				cout << GetNext(0, x1, INF) << endl;
				break;
			}
			case 5: {
				add(x1);
				break;
			}
		}
	}
	return 0;
}

2022/10/22 00:35
加载中...