「线段树」你能回答这些问题吗
作者:互联网
给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:
1、“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 \(max_{x≤l≤r≤y}\Sigma_{i = l}^rA[i]\)。
2、“2 x y”,把 A[x] 改成 y。
对于每个查询指令,输出一个整数表示答案。
输入格式
第一行两个整数N,M。
第二行N个整数A[i]。
接下来M行每行3个整数k,x,y,k=1表示查询(此时如果x>y,请交换x,y),k=2表示修改。
输出格式
对于每个查询指令输出一个整数表示答案。
每个答案占一行。
数据范围
\(N≤500000,M≤100000\)
输入样例:
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 3 2
输出样例:
2
-1
题目题解:
一道线段树求区间最大子段和的题
很简单..模板
//#define fre yes
#include <cstdio>
#include <iostream>
const int N = 500005;
struct Node {
int l, r;
long long lsum, rsum, sum, mx;
} tree[N << 2];
long long ans = 0;
void updown(int k) {
tree[k].sum = tree[k * 2].sum + tree[k * 2 + 1].sum;
tree[k].lsum = std::max(tree[k * 2].lsum, tree[k * 2].sum + tree[k * 2 + 1].lsum);
tree[k].rsum = std::max(tree[k * 2 + 1].rsum, tree[k * 2 + 1].sum + tree[k * 2].rsum);
tree[k].mx = std::max(tree[k * 2].mx, tree[k * 2 + 1].mx);
tree[k].mx = std::max(tree[k].mx, tree[k * 2].rsum + tree[k * 2 + 1].lsum);
}
void build(int k, int l, int r) {
tree[k].l = l; tree[k].r = r;
if(l == r) {
scanf("%lld", &tree[k].sum);
tree[k].lsum = tree[k].rsum = tree[k].mx = tree[k].sum;
return ;
}
int mid = (l + r) >> 1;
build(k * 2, l, mid);
build(k * 2 + 1, mid + 1, r);
updown(k);
}
void change(int k, int x, int y) {
if(tree[k].l == tree[k].r) {
tree[k].lsum = tree[k].rsum = tree[k].mx = tree[k].sum = y;
return ;
}
int mid = (tree[k].l + tree[k].r) >> 1;
if(mid >= x) change(k * 2, x, y);
else change(k * 2 + 1, x, y);
updown(k);
}
Node ask(int k, int l, int r) {
if(tree[k].l >= l && tree[k].r <= r) {
return tree[k];
}
int mid = (tree[k].l + tree[k].r) >> 1;
if(r <= mid) return ask(k * 2, l, r);
if(l > mid) return ask(k * 2 + 1, l, r);
Node a, b, c;
a = ask(k * 2, l, mid);
b = ask(k * 2 + 1, mid + 1, r);
c.sum = a.sum + b.sum;
c.lsum = std::max(a.lsum, a.sum + b.lsum);
c.rsum = std::max(b.rsum, b.sum + a.rsum);
c.mx = std::max(a.rsum + b.lsum, std::max(a.mx, b.mx));
return c;
}
int main() {
static int n, m;
scanf("%d %d", &n, &m);
build(1, 1, n);
for (int i = 1; i <= m; i++) {
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
if(x == 1) {
ans = 0;
if(y > z) std::swap(y, z);
Node w = ask(1, y, z);
printf("%lld\n", w.mx);
}
if(x == 2) {
change(1, y, z);
}
} return 0;
}
标签:rsum,int,tree,线段,回答,mid,问题,lsum,sum 来源: https://www.cnblogs.com/Nicoppa/p/11424092.html