为什么会全 RE?还是说数组不够大?
#include <bits/stdc++.h>
using namespace std;
#define ll int
#define il inline
#define N 100100
ll n, m, a[N], op, u, v, k;
struct trE{
ll val, sz, cnt, tag;
}tre[N * 20];
ll en, son[N][2];
il ll neww(ll val){
tre[++en] = trE{val, 1, 1, rand()};
son[en][0] = son[en][1] = 0;
return en;
}
il void pu(ll p){tre[p].sz = tre[son[p][0]].sz + tre[son[p][1]].sz + tre[p].cnt;}
il void rtt(ll &p, ll d){
ll s = son[p][d];
son[p][d] = son[s][d ^ 1];
son[s][d ^ 1] = p;
pu(p);
pu(s);
p = s;
}
il void add(ll &p, ll val){
if (p == 0) p = neww(val);
else if (tre[p].val == val) tre[p].cnt++;
else{
if (tre[p].val > val){
add (son[p][0], val);
if (tre[son[p][0]].tag > tre[p].tag) rtt(p, 0);
}
else{
add (son[p][1], val);
if (tre[son[p][1]].tag > tre[p].tag) rtt(p, 1);
}
}
pu(p);
}
il void del(ll &p, ll val){
if (tre[p].val > val) del(son[p][0], val);
else if (tre[p].val < val) del(son[p][1], val);
else if (tre[p].cnt > 1) tre[p].cnt--;
else{
if (!son[p][0] && !son[p][1]) p = 0;
else if (!son[p][0]) rtt(p, 1), del(son[p][0], val);
else if (!son[p][1]) rtt(p, 0), del(son[p][1], val);
else{
if (tre[son[p][0]].tag > tre[son[p][1]].tag) rtt(p, 0), del(son[p][1], val);
else rtt(p, 1), del(son[p][0], val);
}
}
if (p) pu(p);
}
il ll rk(ll p, ll k){
if (p == 0) return 0;
if (tre[p].val > k) return rk(son[p][0], k);
else if (tre[p].val == k) return tre[son[p][0]].sz;
else return tre[son[p][0]].sz + tre[p].cnt + rk(son[p][1], k);
}
il ll pre(ll p, ll k){
if (p == 0) return -2147483647;
else if (tre[p].val >= k) return pre(son[p][0], k);
else return max(tre[p].val, pre(son[p][1], k));
}
il ll nxt(ll p, ll k){
if (p == 0) return 2147483647;
else if (tre[p].val <= k) return nxt(son[p][1], k);
else return min(tre[p].val, nxt(son[p][0], k));
}
struct SEG{
ll l, r, rt;
}tr[N * 8];
il void build (ll p, ll l, ll r){
tr[p].l = l, tr[p].r = r;
for (int i = l; i <= r; i++) add(tr[p].rt, a[i]);
if (l == r) return;
ll mid = (l + r) >> 1;
build (p << 1, l, mid);
build (p << 1 | 1, mid + 1, r);
}
il void seg_add(ll p, ll x, ll k){
del(tr[p].rt, a[x]);
add(tr[p].rt, k);
if (tr[p].l == tr[p].r) return;
ll mid = (tr[p].l + tr[p].r) >> 1;
if (x <= mid) seg_add(p << 1, x, k);
else seg_add(p << 1 | 1, x, k);
}
il ll seg_rk(ll p, ll l, ll r, ll k){
if (tr[p].l > r || tr[p].r < l) return 0;
if (tr[p].l >= l && tr[p].r <= r) return rk(tr[p].rt, k);
return seg_rk(p << 1, l, r, k) + seg_rk(p << 1 | 1, l, r, k);
}
il ll seg_kr(ll x, ll y, ll k){
ll l = 0, r = 1e18;
while (l < r){
ll mid = (l + r + 1) >> 1;
if (seg_rk(1, x, y, mid) < k) l = mid;
else r = mid - 1;
}
return r;
}
il ll seg_pre(ll p, ll l, ll r, ll k){
if (tr[p].l > r || tr[p].r < l) return -2147483647;
if (tr[p].l >= l && tr[p].r <= r) return pre(tr[p].rt, k);
return max(seg_pre(p << 1, l, r, k), seg_pre(p << 1 | 1, l, r, k));
}
il ll seg_nxt(ll p, ll l, ll r, ll k){
if (tr[p].l > r || tr[p].r < l) return 2147483647;
if (tr[p].l >= l && tr[p].r <= r) return nxt(tr[p].rt, k);
return min(seg_nxt(p << 1, l, r, k), seg_nxt(p << 1 | 1, l, r, k));
}
int main(){
srand(time(0));
scanf ("%lld %lld", &n, &m);
for (int i = 1; i <= n; i++) scanf ("%lld", &a[i]);
build (1, 1, n);
while (m--){
scanf ("%lld %lld %lld", &op, &u, &v);
if (op == 3){
seg_add(1, u, v);
a[u] = v;
}
else{
scanf ("%lld", &k);
if (op == 1) printf ("%lld\n", seg_rk(1, u, v, k) + 1);
if (op == 2) printf ("%lld\n", seg_kr(u, v, k));
if (op == 4) printf ("%lld\n", seg_pre(1, u, v, k));
if (op == 5) printf ("%lld\n", seg_nxt(1, u, v, k));
}
}
return 0;
}