加过 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;
}
LibreOJ 上评测 AC(开了 32 位指针,没有加 delete)
可以发现加了 delete 之后 RE 了,在 LibreOJ 上 AC 的在洛谷上 MLE & WA。
求教如何修改此代码使其能在洛谷上 AC。/kel