struct SegmentTree {
int l, r;
int dat;
} t[SIZE * 4];
void build(int p, int l, int r) {
t[p].l = l, t[p].r = r;
if (l == r) { t[p].dat = a[l]; return; }
int mid = (l + r) / 2;
build(p*2, l, mid);
build(p*2+1, mid+1, r);
t[p].dat = max(t[p*2].dat, t[p*2+1].dat);
}
build(1, 1, n);
void change(int p, int x, int v) {
if (t[p].l == t[p].r) { t[p].dat = v; return; }
int mid = (t[p].l + t[p].r) / 2;
if (x <= mid) change(p*2, x, v);
else change(p*2+1, x, v);
t[p].dat = max(t[p*2].dat, t[p*2+1].dat);
}
change(1, x, v);
int ask(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r) return t[p].dat;
int mid = (t[p].l + t[p].r) / 2;
int val = 0;
if (l <= mid) val = max(val, ask(p*2, l, r));
if (r > mid) val = max(val, ask(p*2+1, l, r));
return val;
}
cout << ask(1, l, r) << endl;
struct SegmentTree {
int lc, rc;
int dat;
} tr[SIZE * 2];
int root, tot;
int build() {
tot++;
tr[tot].lc = tr[tot].rc = tr[tot].dat = 0;
return tot;
}
tot = 0;
root = build();
void insert(int p, int l, int r, int val, int delta) {
if (l == r) {
tr[p].dat += delta;
return;
}
int mid = (l + r) >> 1;
if (val <= mid) {
if (!tr[p].lc) tr[p].lc = build();
insert(tr[p].lc, l, mid, val, delta);
}
else {
if (!tr[p].rc) tr[p].rc = build();
insert(tr[p].rc, mid + 1, r, val, delta);
}
tr[p].dat = max(tr[tr[p].lc].dat, tr[tr[p].rc].dat);
}
insert(root, 1, n, val, delta);
int merge(int p, int q, int l, int r) {
if (!p) return q;
if (!q) return p;
if (l == r) {
tr[p].dat += tr[q].dat;
return p;
}
int mid = (l + r) >> 1;
tr[p].lc = merge(tr[p].lc, tr[q].lc, l, mid);
tr[p].rc = merge(tr[p].rc, tr[q].rc, mid + 1, r);
tr[p].dat = max(tr[tr[p].lc].dat, tr[tr[p].rc].dat);
return p;
}