线段树
作者:互联网
基本线段树
你能回答这些问题吗
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 5e5+5;
int n, m;
struct Node{
int l, r;
int tsum;
int lsum, rsum;
int sum;
}tree[N*4];
void pushup(Node &node, Node &lnode, Node &rnode)
{
node.sum = lnode.sum + rnode.sum;
node.lsum = max(lnode.lsum, lnode.sum + rnode.lsum);
node.rsum = max(rnode.rsum, rnode.sum + lnode.rsum);
node.tsum = max(max(lnode.tsum, rnode.tsum), lnode.rsum + rnode.lsum);
}
void pushup(int u)
{
pushup(tree[u], tree[u<<1], tree[u<<1|1]);
}
void build(int u, int l, int r)
{
tree[u] = {l, r, 0, 0, 0, 0};
if(l == r)
{
return;
}
int mid = l+r>>1;
build(u<<1, l, mid);
build(u<<1|1, mid+1, r);
pushup(u);
}
//将第x个数改为v
void modify(int u, int x, int v)
{
if(tree[u].l == tree[u].r)
{
tree[u] = {tree[u].l, tree[u].r, v, v, v, v}; //lsum, rsum必须有元素
return;
}
int mid = tree[u].l + tree[u].r >> 1;
if(x <= mid)
{
modify(u<<1, x, v);
}
else
{
modify(u<<1|1, x, v);
}
pushup(u);
}
//查询区间L~R的最大连续子段和
Node query(int u, int L, int R)
{
if(tree[u].l >= L && tree[u].r <= R)
{
return tree[u];
}
int mid = tree[u].l + tree[u].r >> 1;
Node ltree, rtree;
bool haveL = false, haveR = false;
if(mid >= L) //包含左子树
{
ltree = query(u<<1, L, R);
haveL = true;
}
if(mid+1 <= R) //包含右子树
{
rtree = query(u<<1|1, L, R);
haveR = true;
}
if(haveL && haveR)
{
Node ans;
pushup(ans, ltree, rtree);
return ans;
}
else if(haveL)
{
return ltree;
}
else if(haveR)
{
return rtree;
}
}
int main()
{
cin >> n >> m;
build(1, 1, n);
for(int i = 1; i <= n; ++ i)
{
int tp;
scanf("%d", &tp);
modify(1, i, tp);
}
while(m --)
{
int k, x, y;
scanf("%d%d%d", &k, &x, &y);
if(k == 1)
{
if(x > y) swap(x, y);
Node ans = query(1, x, y);
printf("%d\n", ans.tsum);
}
else
{
modify(1, x, y);
}
}
return 0;
}
标签:Node,node,lnode,int,线段,rnode,sum 来源: https://www.cnblogs.com/chaosliang/p/14728268.html