luogu SP1043 GSS1 - Can you answer these queries I
Posted qingyuyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu SP1043 GSS1 - Can you answer these queries I相关的知识,希望对你有一定的参考价值。
//单点修改 pushup
//查询区间内的最大字段和
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 500010;
int n, m;
int w[N];
struct Node
{
//端点
int l, r;
int sum;//区间和
//最大前缀和
//分两种:没有超过mid,超过mid
//没有超过mid的就是,当前区间左儿子的最大字段和
//超过mid的就是,左边的sum+右边的lmax
int lmax;
//最大后缀和
////横跨左右区间的最大子段和==左子区间的最大后缀和+右子区间的最大前缀和
int rmax;
//最大连续子段和
//max(左子区间的最大子段和,右子区间的最大子段和,横跨左右区间的最大子段和)
int tmax;
} tr[N * 4];
//u是l和r的父节点
void pushup(Node &u, Node &l, Node &r)
{
//总和
u.sum = l.sum + r.sum;
//最大前缀
u.lmax = max(l.lmax, l.sum + r.lmax);
//最大后缀
u.rmax = max(r.rmax, r.sum + l.rmax);
//最大子段和
u.tmax = max(max(l.tmax, r.tmax), l.rmax + r.lmax);
}
void pushup(int u)
{
//根节点,左子节点,右子节点
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
//
void build(int u, int l, int r)
{
//如果是叶节点
if (l == r)
//左右节点,总和(就一个数),最大前缀和,最大后缀和,最大子段和
tr[u] = {l, r, w[r], w[r], w[r], w[r]};
else
{
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
//修改函数
// 在x这个位置,把它改成v
int modify(int u, int x, int v)
{
//如果到了叶节点
if (tr[u].l == x && tr[u].r == x)
tr[u] = {x, x, v, v, v, v};
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid)
modify(u << 1, x, v);
else
modify(u << 1 | 1, x, v);
pushup(u);
}
}
//查询
//数中查询到的节点编号,左端点,右端点
Node query(int u, int l, int r)
{
//如果已经呗包含了,就返回
if (tr[u].l >= l && tr[u].r <= r)
return tr[u];
else
{
//中点
int mid = tr[u].l + tr[u].r >> 1;
//完全在左边
if (r <= mid)
return query(u << 1, l, r);
//完全在右边
else if (l > mid)
return query(u << 1 | 1, l, r);
//说明左右两边都有
else
{
//找左右两边
auto left = query(u << 1, l, r);
auto right = query(u << 1 | 1, l, r);
Node res;
pushup(res, left, right);
return res;
}
}
}
int main()
{
cin>>n;
for (int i = 1; i <= n; i ++ )
scanf("%d", &w[i]);
build(1, 1, n);
cin>>m;
int k, x, y;
while (m -- )
{
k=1;
cin>>x>>y;
if (k == 1)
{
if (x > y)
swap(x, y);
printf("%d
", query(1, x, y).tmax);
}
//修改
else
modify(1, x, y);
}
return 0;
}
以上是关于luogu SP1043 GSS1 - Can you answer these queries I的主要内容,如果未能解决你的问题,请参考以下文章
SP1043 GSS1 - Can you answer these queries I 线段树
「SP1043」GSS1 - Can you answer these queries I
SP1043 GSS1 - Can you answer these queries I(猫树)
SP1043GSS1 - Can you answer these queries I
SP1043 GSS1 - Can you answer these queries I(线段树,区间最大子段和(静态))
$SP1043$ $GSS1$ $-$ $Can$ $you$ $answer$ $these$ $queries$ $I$