指针写法 RE & MLE 求助(返回 6)
查看原帖
指针写法 RE & MLE 求助(返回 6)
490879
徐崇瑜楼主2023/4/7 10:33

加过 delete 的代码:

template<typename _Num, _Num _len, _Num _min, _Num _max> class sgt {
	private:
		class stv {
			public:
				struct node_t {
					_Num cnt;
					node_t *left, *right;
					node_t() : cnt(0), left(nullptr), right(nullptr) {}
				} *root;
				stv() : root(new node_t) {}
		};
		typename stv::node_t *ptr[32];
		_Num cnt;
		struct node_t {
			stv *val;
			node_t *left, *right;
			node_t() : val(new stv), left(nullptr), right(nullptr) {}
		} *root, *t[_len * 2];
		_Num sumOfPointersLeftNow() {
			static _Num res;
			res = 0;
			for(typename stv::node_t *i : ptr)
				if(i && i -> left)
					res += i -> left -> cnt;
			return res;
		}
		_Num sumOfPointersRightNow() {
			static _Num res;
			res = 0;
			for(typename stv::node_t *i : ptr)
				if(i && i -> right)
					res += i -> right -> cnt;
			return res;
		}
		void movePointersLeftAll() {
			for(typename stv::node_t *&i : ptr)
				if(i)
					i = i -> left;
		}
		void movePointersRightAll() {
			for(typename stv::node_t *&i : ptr)
				if(i)
					i = i -> right;
		}
		void collectPointers(node_t *p, _Num l, _Num r, _Num k) {
			ptr[cnt++] = p -> val -> root;
			if(l + 1 == r)
				return;
			int mid = l + r >> 1;
			if(k < mid)
				collectPointers(p -> left, l, mid, k);
			else
				collectPointers(p -> right, mid, r, k);
		}
		void collectPointers(node_t *p, _Num l, _Num r, _Num a, _Num b) {
			if(r <= a || b <= l)
				return;
			if(a <= l && r <= b)
				return ptr[cnt++] = p -> val -> root, void();
			int mid = l + r >> 1;
			collectPointers(p -> left, l, mid, a, b),
			collectPointers(p -> right, mid, r, a, b);
		}
		void collectPointers(_Num k) {
			cnt = 0;
			for(typename stv::node_t *&i : ptr)
				i = nullptr;
			collectPointers(root, 0, _len, k); 
		}
		void collectPointers(_Num l, _Num r) {
			cnt = 0;
			for(typename stv::node_t *&i : ptr)
				i = nullptr;
			collectPointers(root, 0, _len, l, r);
		}
		void modify(_Num k, _Num x, _Num diff) {
			static _Num L, R;
			collectPointers(k);
			L = _min, R = _max;
			while(L + 1 < R) {
				_Num mid = L + R >> 1;
				for(typename stv::node_t *i : ptr)
					if(i) {
						i -> cnt += diff;
						if(!i -> cnt)
							delete i;
					}
				if(x < mid) {
					for(typename stv::node_t *i : ptr)
						if(i && !i -> left)
							i -> left = new typename stv::node_t;
					movePointersLeftAll(), R = mid;
				} else {
					for(typename stv::node_t *i : ptr)
						if(i && !i -> right)
							i -> right = new typename stv::node_t;
					movePointersRightAll(), L = mid;
				}
			}
			for(typename stv::node_t *i : ptr)
				if(i) {
					i -> cnt += diff;
					if(!i -> cnt)
						delete i;
				}
		}
	public:
		_Num getRank(_Num l, _Num r, _Num x) {
			static _Num L, R, res;
			collectPointers(l, r);
			res = 0, L = _min, R = _max;
			while(L + 1 < R) {
				_Num mid = L + R >> 1;
				if(x < mid)
					R = mid, movePointersLeftAll();
				else
					res += sumOfPointersLeftNow(), 
					movePointersRightAll(), L = mid;
			}
			return res;
		}
		_Num getValue(_Num l, _Num r, _Num x) {
			static _Num L, R;
			if(x == -1)
				return -2147483647;
			if(x == root -> val -> root -> cnt)
				return 2147483647;
			collectPointers(l, r);
			L = _min, R = _max;
			while(L + 1 < R) {
				_Num mid = L + R >> 1;
				if(x < sumOfPointersLeftNow())
					R = mid, movePointersLeftAll();
				else
					x -= sumOfPointersLeftNow(), 
					movePointersRightAll(), L = mid;
			}
			return L;
		}
		_Num getPrev(_Num l, _Num r, _Num x) {
			return getValue(l, r, getRank(l, r, x) - 1);
		}
		_Num getNext(_Num l, _Num r, _Num x) {
			return getValue(l, r, getRank(l, r, x + 1));
		}
		void insert(_Num k, _Num x) {
			modify(k, x, 1);
		}
		void erase(_Num k, _Num x) {
			modify(k, x, -1);
		}
		sgt() {
			for(node_t *&i : t)
				i = new node_t;
			for(_Num i = _len * 2 - 2; i > 0; i -= 2)
				t[i - 1 >> 1] -> right = t[i];
			for(_Num i = _len * 2 - 3; i > 0; i -= 2)
				t[i - 1 >> 1] -> left = t[i];
			root = t[0];
		}
};
sgt<int, 65536, 0, (1 << 27)> f;
int n, q, a[65536];
int main() {
	__builtin_scanf("%d%d", &n, &q);
	for(int i = 1; i <= n; i++)
		__builtin_scanf("%d", &a[i]), f.insert(i, a[i]);
	for(int op, l, r, x; q--; ) {
		__builtin_scanf("%d", &op);
		if(op == 1)
			__builtin_scanf("%d%d%d", &l, &r, &x),
			__builtin_printf("%d\n", f.getRank(l, r + 1, x) + 1);
		else if(op == 2)
			__builtin_scanf("%d%d%d", &l, &r, &x),
			__builtin_printf("%d\n", f.getValue(l, r + 1, x - 1));
		else if(op == 3)
			__builtin_scanf("%d%d", &l, &x),
			f.erase(l, a[l]), f.insert(l, a[l] = x);
		else if(op == 4)
			__builtin_scanf("%d%d%d", &l, &r, &x),
			__builtin_printf("%d\n", f.getPrev(l, r + 1, x));
		else if(op == 5)
			__builtin_scanf("%d%d%d", &l, &r, &x),
			__builtin_printf("%d\n", f.getNext(l, r + 1, x));
	}
	return 0;
}

没有加 delete

加了 delete

LibreOJ 上评测 AC(开了 32 位指针,没有加 delete)

可以发现加了 delete 之后 RE 了,在 LibreOJ 上 AC 的在洛谷上 MLE & WA。

求教如何修改此代码使其能在洛谷上 AC。/kel

2023/4/7 10:33
加载中...