Code
先放代码
template<class Info>
struct segment{
private:
#define ls (u * 2 + 1)
#define rs (u * 2 + 2)
struct Node{
int l, r;
Info info;
};
vector<Node> tr;
public:
using info_type = Info;
segment() {}
segment(int n, Info v = Info()){
vector<Info> a(n, v);
init(a);
}
template<class T>
segment(const vector<T> &a){
init(a);
}
template<class T>
void init(const vector<T> &a){
int n = a.size();
tr.resize(n << 2);
build(0, 0, n - 1, a);
}
private:
void pushup(int u){
tr[u].info = tr[ls].info + tr[rs].info;
}
template<class T>
void build(int u, int l, int r, const vector<T> &a){
tr[u].l = l;
tr[u].r = r;
if(l == r){
tr[u].info = a[l];
return;
}
int mid = (l + r) >> 1;
build(ls, l, mid, a);
build(rs, mid + 1, r, a);
pushup(u);
}
void modify(int u, int x, const Info &v){
if(tr[u].l == tr[u].r){
tr[u].info = v;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if(x <= mid) modify(ls, x, v);
else modify(rs, x, v);
pushup(u);
}
void add(int u, int x, const Info &v){
if(tr[u].l == tr[u].r){
tr[u].info = tr[u].info + v;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if(x <= mid) add(ls, x, v);
else add(rs, x, v);
pushup(u);
}
Info query(int u, int l, int r){
if(l <= tr[u].l && r >= tr[u].r) return tr[u].info;
int mid = tr[u].l + tr[u].r >> 1;
if(r <= mid) return query(ls, l, r);
if(l > mid) return query(rs, l, r);
return query(ls, l, r) + query(rs, l, r);
}
Info get(int u, int x){
if(tr[u].l == tr[u].r) return tr[u].info;
int mid = tr[u].l + tr[u].r >> 1;
if(x <= mid) return get(ls, x);
else return get(rs, x);
}
public:
void modify(int x, const Info &v){
modify(0, x, v);
}
void add(int x, const Info &v){
add(0, x, v);
}
Info query(int l, int r){
return query(0, l, r);
}
Info get(int x){
return get(0, x);
}
#undef ls
#undef rs
};
Initialize
segment<Info>(int n, Info v = Info());
初始化大小为 nnn 的线段树,每一项为 vvv.
1≤n≤1071 \le n \le 10^71≤n≤107
segment<Info>(const vector<T> &a);
使用 aaa 初始化大小为 ∣a∣|a|∣a∣ 的线段树.
1≤∣a∣≤1071 \le |a| \le 10^71≤∣a∣≤107
其中 Info\texttt{Info}Info 类需要支持 +++(合并信息)操作.
Modify
void segment<Info>::modify(int x, const Info &v);
执行 ax←va_x \gets vax←v
0≤x<n0 \le x < n0≤x<n
void segment<Info>::add(int x, const Info &v);
执行 ax←ax+va_x \gets a_x+vax←ax+v
0≤x<n0 \le x < n0≤x<n
Query
Info segment<Info>::query(int l, int r);
求 al+al+1+⋯+ara_l+a_l+1+\cdots+a_ral+al+1+⋯+ar.
0≤l≤r<n0 \le l \le r < n0≤l≤r<n
Info segment<Info>::get(int x);
获得 axa_xax 的值。
0≤x<n0 \le x < n0≤x<n
Example
给定序列 a=(a1,a2,⋯ ,an)a=(a_1,a_2,\cdots,a_n)a=(a1,a2,⋯,an),有 mmm 个操作分两种:
- set(p,v)\operatorname{set}(p,v)set(p,v):执行 ap=va_p=vap=v.
- query(l,r)\operatorname{query}(l,r)query(l,r):求 max[u,v]∈[l,r](∑i=uvai)\max\limits_{[u,v] \in [l,r]} (\sum\limits_{i=u}^v a_i)[u,v]∈[l,r]max(i=u∑vai).
int max(int a, int b, int c) { return max(a, max(b, c)); }
struct Info {
int sum, lmax, rmax, ans;
Info(int _sum = 0, int _lmax = 0, int _rmax = 0, int _ans = 0):
sum(_sum), lmax(_lmax), rmax(_rmax), ans(_ans) {}
};
Info operator+(const Info &lhs, const Info &rhs) {
Info res;
res.sum = lhs.sum + rhs.sum;
res.lmax = max(lhs.lmax, lhs.sum + rhs.lmax);
res.rmax = max(rhs.rmax, lhs.rmax + rhs.sum);
res.ans = max(lhs.ans, rhs.ans, lhs.rmax + rhs.lmax);
return res;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<Info> info(n);
for (int i = 0, x; i < n; i++) {
cin >> x;
info[i] = Info(x, x, x, x);
}
segment<Info> seg(info);
for (int i = 0, op, x, y; i < m; i++) {
cin >> op >> x >> y;
if (op == 1) {
x--, y--;
if (x > y) swap(x, y);
cout << seg.query(x, y).ans << endl;
}
else {
x--;
seg.modify(x, Info(y, y, y, y));
}
}
return 0;
}

1144

被折叠的 条评论
为什么被折叠?



