(单点修改,区间求最值)
struct SegTree {struct node {int l, r, mi;}tr[N<<2];void pushup(int u) {tr[u].mi = min(tr[u<<1].mi, tr[u<<1|1].mi);}void build(int u, int l, int r) {tr[u].l = l, tr[u].r = r;tr[u].mi = INF;if (l == r) {tr[u].mi = a[r];return ;}int mid = l+r>>1;build(u<<1, l, mid);build(u<<1|1, mid+1, r);pushup(u);}void update(int u, int p, int k) {if (tr[u].l == tr[u].r) {tr[u].mi = k;a[p] = k;return ;}int mid = tr[u].l+tr[u].r>>1;if (p <= mid) {update(u<<1, p, k);} else {update(u<<1|1, p, k);}pushup(u);}int query(int u, int L, int R) {if (tr[u].l>=L && tr[u].r<=R) {return tr[u].mi;}int mid = tr[u].l+tr[u].r>>1;int res = INF;if (mid >= L)res = min(res, query(u<<1, L, R));if (mid < R)res = min(res, query(u<<1|1, L, R));return res;}}tree;
(区间修改,区间求最值)
struct SegmentTree {struct node {int l, r;int mx, tag;}tr[N<<2];void pushup(int u) {tr[u].mx = max(tr[u<<1].mx, tr[u<<1|1].mx);}void eval(int u, int tag) {tr[u].tag += tag;tr[u].mx += tag;}void pushdown(int u) {eval(u<<1, tr[u].tag);eval(u<<1|1, tr[u].tag);tr[u].tag = 0;}void build(int u, int l, int r) {tr[u].l = l, tr[u].r = r;tr[u].tag = 0, tr[u].mx = -0x3f3f3f3f;if (l == r) {tr[u].mx = w[l];return ;}int mid = l+r>>1;build(u<<1, l, mid);build(u<<1|1, mid+1, r);pushup(u);}void update(int u, int l, int r, int k) {if (l<=tr[u].l && r>=tr[u].r) {eval(u, k);return;}pushdown(u);int mid = tr[u].l+tr[u].r>>1;if (l <= mid)update(u<<1, l, r, k);if (r > mid)update(u<<1|1, l, r, k);pushup(u);}int query(int u, int l, int r) {if (l <= tr[u].l && r >= tr[u].r)return tr[u].mx;pushdown(u);int mid = tr[u].l+tr[u].r>>1;int res = 0;if (l <= mid)res = max(res, query(u<<1, l, r));if (r > mid)res = max(res, query(u<<1|1, l, r));pushup(u);return res;}}tree;
(区间+k,区间求和)
struct SegTr{struct node {int l, r;int sum, tag;}tr[N<<2];void pushup(int u) {tr[u].sum = tr[u<<1].sum+tr[u<<1|1].sum;}void eval(int u, int tag) {tr[u].sum += (tr[u].r-tr[u].l+1)*tag;tr[u].tag += tag;}void pushdown(int u) {if (tr[u].tag) {eval(u<<1, tr[u].tag);eval(u<<1|1, tr[u].tag);tr[u].tag = 0;}}void build(int u, int l, int r) {tr[u].l = l, tr[u].r = r;tr[u].tag = 0;if (l == r) {tr[u].sum = b[r];return ;}int mid = l+r>>1;build(u<<1, l, mid);build(u<<1|1, mid+1, r);pushup(u);}void update(int u, int l, int r, int k) {if (tr[u].l>=l && tr[u].r<=r) {eval(u, k);return ;}pushdown(u);int mid = tr[u].l+tr[u].r>>1;if (l <= mid)update(u<<1, l, r, k);if (r > mid)update(u<<1|1, l, r, k);pushup(u);}int query(int u, int l, int r) {if (tr[u].l>=l && tr[u].r<=r)return tr[u].sum;pushdown(u);int mid = tr[u].l+tr[u].r>>1;int res = 0;if (l <= mid)res += query(u<<1, l, r);if (r > mid)res += query(u<<1|1, l, r);return res;}}tree;
(单点修改,区间求最长连续01序列)
struct SegTree {struct node {int l, r, len;int lv, rv;int lmx, rmx, mx;}tr[N<<2];void pushup(int u) {tr[u].lmx = tr[u<<1].lmx;tr[u].rmx = tr[u<<1|1].rmx;tr[u].lv = tr[u<<1].lv;tr[u].rv = tr[u<<1|1].rv;tr[u].mx = max(tr[u<<1].mx, tr[u<<1|1].mx);if (tr[u<<1].rv != tr[u<<1|1].lv) {tr[u].mx = max(tr[u].mx, tr[u<<1].rmx+tr[u<<1|1].lmx);if (tr[u<<1].mx == tr[u<<1].len) {tr[u].lmx = tr[u<<1|1].lmx+tr[u<<1].len;}if (tr[u<<1|1].mx == tr[u<<1|1].len) {tr[u].rmx = tr[u<<1].rmx+tr[u<<1|1].len;}}}void build(int u, int l, int r) {tr[u].l = l, tr[u].r = r;tr[u].len = r-l+1;if (l == r) {tr[u].lv = tr[u].rv = 1;tr[u].lmx = tr[u].rmx = 1;tr[u].mx = 1;return ;}int mid = l+r>>1;build(u<<1, l, mid);build(u<<1|1, mid+1, r);pushup(u);}void update(int u, int pos) {if (tr[u].l == tr[u].r) {tr[u].lv ^= 1;tr[u].rv = tr[u].lv;return ;}int mid = tr[u].l+tr[u].r>>1;if (pos <= mid)update(u<<1, pos);if (pos > mid)update(u<<1|1, pos);pushup(u);}int query() {return max(tr[1].mx, max(tr[1].lmx, tr[1].rmx));}}tree;
(区间修改,区间求最长连续0序列)
struct SegTree {
struct node {
int l, r, len;
int lmx, rmx, sum;
int tag;
}tr[N<<2];
void pushup(int u) {
if (tr[u<<1].sum == tr[u<<1].len) {
tr[u].lmx = tr[u<<1].len+tr[u<<1|1].lmx;
} else {
tr[u].lmx = tr[u<<1].lmx;
}
if (tr[u<<1|1].sum == tr[u<<1|1].len) {
tr[u].rmx = tr[u<<1].rmx+tr[u<<1|1].len;
} else {
tr[u].rmx = tr[u<<1|1].rmx;
}
tr[u].sum = max(tr[u<<1].rmx+tr[u<<1|1].lmx, max(tr[u<<1].sum, tr[u<<1|1].sum));
}
void build(int u, int l, int r) {
tr[u].l = l, tr[u].r = r;
tr[u].tag = 0;
tr[u].sum = tr[u].len = tr[u].lmx = tr[u].rmx = r-l+1;
if (l == r) {
return ;
}
int mid = l+r>>1;
build(u<<1, l, mid);
build(u<<1|1, mid+1, r);
pushup(u);
}
void eval(int u, int tag) {
if (tag == 1) {
tr[u].tag = 1;
tr[u].sum = tr[u].lmx = tr[u].rmx = 0;
} else if (tag == 2) {
tr[u].tag = 2;
tr[u].sum = tr[u].lmx = tr[u].rmx = tr[u].len;
}
}
void pushdown(int u) {
if (tr[u].tag == 0) {
return ;
} else if (tr[u].tag == 1) {
eval(u<<1, 1);
eval(u<<1|1, 1);
} else if (tr[u].tag == 2) {
eval(u<<1, 2);
eval(u<<1|1, 2);
}
tr[u].tag = 0;
}
void update(int u, int l, int r, int tag) {
if (tr[u].l>=l && tr[u].r<=r) {
eval(u, tag);
return ;
}
pushdown(u);
int mid = tr[u].l+tr[u].r>>1;
if (l <= mid)
update(u<<1, l, r, tag);
if (r > mid)
update(u<<1|1, l, r, tag);
pushup(u);
}
int query(int u, int l, int r, int len) {
if (l == r)
return l;
pushdown(u);
int mid = l+r>>1;
if (tr[u<<1].sum >= len)
return query(u<<1, l, mid, len);
if (tr[u<<1].rmx+tr[u<<1|1].lmx >= len) {
return mid-tr[u<<1].rmx+1;
} else {
return query(u<<1|1, mid+1, r, len);
}
}
}tree;
拆位线段树(区间异或x,区间求和)
struct SegTree {
struct node {
int l, r;
int tag, sum;
}tr[21][N*4];
void pushup(int id, int u) {
tr[id][u].sum = tr[id][u<<1].sum+tr[id][u<<1|1].sum;
}
void build(int id, int u, int l, int r) {
tr[id][u].l = l, tr[id][u].r = r;
if (l == r) {
tr[id][u].sum = (a[l]&(1<<id))!=0;
return ;
}
int mid = l + r >> 1;
build(id, u<<1, l, mid);
build(id, u<<1|1, mid+1, r);
pushup(id, u);
}
void eval(int id, int u) {
int len = tr[id][u].r - tr[id][u].l + 1;
tr[id][u].sum = len - tr[id][u].sum;
tr[id][u].tag ^= 1;
}
void pushdown(int id, int u) {
if (tr[id][u].tag != 0) {
eval(id, u<<1);
eval(id, u<<1|1);
tr[id][u].tag = 0;
}
}
void update(int id, int u, int l, int r) {
if (tr[id][u].l >= l && tr[id][u].r <= r) {
eval(id, u);
return ;
}
pushdown(id, u);
int mid = tr[id][u].l + tr[id][u].r >> 1;
if (l <= mid)
update(id, u<<1, l, r);
if (r > mid)
update(id, u<<1|1, l, r);
pushup(id, u);
}
int query(int id, int u, int l, int r) {
if (tr[id][u].l >= l && tr[id][u].r <= r)
return tr[id][u].sum;
pushdown(id, u);
int res = 0;
int mid = tr[id][u].l + tr[id][u].r >> 1;
if (l <= mid)
res += query(id, u<<1, l, r);
if (r > mid)
res += query(id, u<<1|1, l, r);
return res;
}
}tree;
