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());
初始化大小为
n
n
n 的线段树,每一项为
v
v
v.
1
≤
n
≤
1
0
7
1 \le n \le 10^7
1≤n≤107
segment<Info>(const vector<T> &a);
使用
a
a
a 初始化大小为
∣
a
∣
|a|
∣a∣ 的线段树.
1
≤
∣
a
∣
≤
1
0
7
1 \le |a| \le 10^7
1≤∣a∣≤107
其中 Info \texttt{Info} Info 类需要支持 + + +(合并信息)操作.
Modify
void segment<Info>::modify(int x, const Info &v);
执行
a
x
←
v
a_x \gets v
ax←v
0
≤
x
<
n
0 \le x < n
0≤x<n
void segment<Info>::add(int x, const Info &v);
执行
a
x
←
a
x
+
v
a_x \gets a_x+v
ax←ax+v
0
≤
x
<
n
0 \le x < n
0≤x<n
Query
Info segment<Info>::query(int l, int r);
求
a
l
+
a
l
+
1
+
⋯
+
a
r
a_l+a_l+1+\cdots+a_r
al+al+1+⋯+ar.
0
≤
l
≤
r
<
n
0 \le l \le r < n
0≤l≤r<n
Info segment<Info>::get(int x);
获得
a
x
a_x
ax 的值。
0
≤
x
<
n
0 \le x < n
0≤x<n
Example
给定序列 a = ( a 1 , a 2 , ⋯ , a n ) a=(a_1,a_2,\cdots,a_n) a=(a1,a2,⋯,an),有 m m m 个操作分两种:
- set ( p , v ) \operatorname{set}(p,v) set(p,v):执行 a p = v a_p=v ap=v.
- query ( l , r ) \operatorname{query}(l,r) query(l,r):求 max [ u , v ] ∈ [ l , r ] ( ∑ i = u v a i ) \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;
}