AmiyaCast @ 2024-08-12 10:01:31
maxn依次改成了1e5(除了#1全MLE),1e6(两个MLE) 2e6(AC),得到的MLE越来越少,为啥呢
#include <algorithm>
#include <cstdio>
#include <iostream>
#define maxn 2000005
#define INF (1 << 30)
int n, m;
struct treap { // 直接维护成数据结构,可以直接用
int l[maxn], r[maxn], val[maxn], rnd[maxn], size_[maxn], w[maxn];
int sz, ans, rt;
void pushup(int x) {
size_[x] = size_[l[x]] + size_[r[x]] + w[x];
}
void lrotate(int &k) {//左旋
int t = r[k];
r[k] = l[t];
l[t] = k;
size_[t] = size_[k];
pushup(k);
k = t;
}
void rrotate(int &k) {//右旋
int t = l[k];
l[k] = r[t];
r[t] = k;
size_[t] = size_[k];
pushup(k);
k = t;
}
void insert(int &k, int x) { // 插入
if (!k) {
sz++;
k = sz;
size_[k] = 1;
w[k] = 1;
val[k] = x;
rnd[k] = rand();
return;
}
size_[k]++;
if (val[k] == x) {
w[k]++;
} else if (val[k] < x) {
insert(r[k], x);
if (rnd[r[k]] < rnd[k]) lrotate(k);
} else {
insert(l[k], x);
if (rnd[l[k]] < rnd[k]) rrotate(k);
}
}
bool del(int &k, int x) { // 删除节点
if (!k) return false;
if (val[k] == x) {
if (w[k] > 1) {
w[k]--;
size_[k]--;
return true;
}
if (l[k] == 0 || r[k] == 0) {
k = l[k] + r[k];
return true;
} else if (rnd[l[k]] < rnd[r[k]]) {
rrotate(k);
return del(k, x);
} else {
lrotate(k);
return del(k, x);
}
} else if (val[k] < x) {
bool succ = del(r[k], x);
if (succ) size_[k]--;
return succ;
} else {
bool succ = del(l[k], x);
if (succ) size_[k]--;
return succ;
}
}
int queryrank(int k, int x) {//查询有多少个比自己小的数
if (!k) return 0;
if (val[k] == x)
return size_[l[k]];
else if (x > val[k]) {
return size_[l[k]] + w[k] + queryrank(r[k], x);
} else
return queryrank(l[k], x);
}
int querynum(int k, int x) {//子树k中排名是x的数
if (!k) return 0;
if (x <= size_[l[k]])
return querynum(l[k], x);
else if (x > size_[l[k]] + w[k])
return querynum(r[k], x - size_[l[k]] - w[k]);
else
return val[k];
}
void querypre(int k, int x) {//用ans返回节点编号
if (!k) return;
if (val[k] < x)
ans = k, querypre(r[k], x);
else
querypre(l[k], x);
}
void querysub(int k, int x) {//用ans返回节点编号
if (!k) return;
if (val[k] > x)
ans = k, querysub(l[k], x);
else
querysub(r[k], x);
}
} T;
int main() {
srand(123);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i){
int x; scanf("%d", &x);
T.insert(T.rt, x);
}
int opt, x, last = 0, ans = 0;
for (int i = 1; i <= m; i++) {
scanf("%d%d", &opt, &x);
x ^= last;
if (opt == 1)
T.insert(T.rt, x);//插入x
else if (opt == 2)
T.del(T.rt, x);//删除一个x
else if (opt == 3) {
ans ^= (last = T.queryrank(T.rt, x) + 1);//查询x的排名多少个比x小的数 + 1
} else if (opt == 4) {
ans ^= (last = T.querynum(T.rt, x));//查询排名是x的数 x是0则返回0
} else if (opt == 5) {
T.ans = 0;
T.querypre(T.rt, x);
ans ^= (last = T.val[T.ans]);//查询x的前去
} else if (opt == 6) {
T.ans = 0;
T.querysub(T.rt, x);
ans ^= (last = T.val[T.ans]);//查询x的后记
}
}
printf("%d\n", ans);
return 0;
}
by eEfiuys @ 2024-08-12 10:04:31
@AmiyaCast 数组开小,访问越界,可能导致任何结果
by AmiyaCast @ 2024-08-12 11:01:19
@aqx_AK_xyf 感谢dalao指点!