使用了 set<int> suf_min 维护,通过玩样例发现当其中值为 [3,4,5] 时,一个迭代器 it 指向 3,但是 ++it 后,迭代器没有指向 4 反而指向了 5,又进行一次 --it 发现才指向 4,请问代码哪里有问题,或者猜测是哪里访问越界了,但是在线IDE运行却没有报错?
贴上测试代码以及相关内容。
#include <cstdio>
#include <set>
#include <iostream>
using namespace std;
int n, q, a[100010], inv[100010];
long long ans;
set<int> suf_min;
struct Segment_Tree {
#define lson (idx << 1 )
#define rson (idx << 1 | 1)
struct node {
int l, r, minn;
} tree[100010 << 2];
void pushup(int idx) {
tree[idx].minn = min(tree[lson].minn, tree[rson].minn);
}
void build(int idx, int l, int r) {
tree[idx] = {l, r, n + 1};
if (l == r) return tree[idx].minn = a[l], void();
int mid = (l + r) >> 1;
build(lson, l, mid), build(rson, mid + 1, r), pushup(idx);
} int query(int idx, int l, int r) {
if (tree[idx].l > r || tree[idx].r < l) return n + 1;
if (l <= tree[idx].l && tree[idx].r <= r) return tree[idx].minn;
return min(query(lson, l, r), query(rson, l, r));
} void modify(int idx, int p, int v) {
if (tree[idx].l > p || tree[idx].r < p) return;
if (tree[idx].l == tree[idx].r) return tree[idx].minn = v, void();
modify(lson, p, v), modify(rson, p, v), pushup(idx);
}
#undef lson
#undef rson
} yzh;
struct Bit_Tree {
constexpr inline int lowbit(int x) {
return x & -x;
}
int tree[100010];
void modify(int p, int v) {
for (int i = p; i <= n; i += lowbit(i)) tree[i] += v;
}
int query(int p) {
int res = 0;
for (int i = p; i; i ^= lowbit(i)) res += tree[i];
return res;
}
int query(int l, int r) {
return query(r) - query(l - 1);
}
} marked_value, marked_idx, removed_value, removed_idx;
void mark(int i) {
suf_min.insert(i), marked_value.modify(a[i], 1), marked_idx.modify(i, 1);
ans += (n - a[i] - removed_value.query(1, a[i])) - (n - i - removed_idx.query(1, i));
}
void remove(int i) {
ans -= (n - a[i] - removed_value.query(1, a[i])) - (n - i - removed_idx.query(1, i));
marked_value.modify(a[i], -1), marked_idx.modify(i, -1);
int L = n, R = 0;
// -------------------------------------------------------------------------------------
auto it = suf_min.find(i);
cout << "Suf_set info ->";
for (auto x : suf_min) cout << x << ' ';
cout << endl;
cout << *it << endl;
++it;
cout << *it << endl;
--it;
cout << *it << endl;
--it;
cout << *it << endl;
// -------------------------------------------------------------------------------------
exit(0);
if (it != suf_min.end()) R = *it;
else R = n + 1;
--it;
if (it != suf_min.begin()) L = *--it;
else L = 1;
suf_min.erase(suf_min.find(a[i]));
while (L < R) {
int j = yzh.query(1, L, R - 1);
if (j == n + 1) break;
j = inv[j];
if (a[j] < (R == n + 1 ? n + 1 : a[R])) mark(j);
L = j + 1;
}
}
signed main() {
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), inv[a[i]] = i;
yzh.build(1, 1, n), ans = n;
int minn = n + 1;
for (int i = n; i >= 1; --i) if (a[i] < minn) minn = a[i], mark(i);
// printf("%lld ", ans);
for (int i = 1; i <= q; ++i) {
int x;
scanf("%d", &x), yzh.modify(1, x, n + 1);
if (suf_min.count(a[x])) remove(x);
ans += marked_value.query(a[x], n) - 1 - marked_idx.query(x, n) - 1 - 1;
removed_value.modify(a[x], 1), removed_idx.modify(x, 1);
// printf("%lld ", ans);
}
return 0;
}
输入
5 2
3 4 1 2 5
3 2
输出
Suf_set info ->3 4 5
3
5
4
3