模板——线段树维护最大子段和 SP1716 GSS3 - Can you answer these queries III

${\color{Pink}{>>Question}}$

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define ll long long
 7 using namespace std;
 8
 9 template <typename T> void in(T &x) {
10     x = 0; T f = 1; char ch = getchar();
11     while(!isdigit(ch)) {if(ch == ‘-‘) f = -1; ch = getchar();}
12     while(isdigit(ch)) {x = 10*x + ch - ‘0‘; ch = getchar();}
13     x *= f;
14 }
15
16 template <typename T> void out(T x) {
17     if(x < 0) putchar(‘-‘),x = -x;
18     if(x > 9) out(x/10);
19     putchar(x%10 + ‘0‘);
20 }
21
22 //------------------------------------------------------------
23
24 const int N = 50005;
25
26 int n,q,a;
27
28 struct node {
29     int lm,rm,all,sum;
30 }t[N<<2];
31
32 void P_up(node &u,node ls,node rs) {
33     u.sum = ls.sum + rs.sum;
34     u.all = max(max(ls.all,rs.all),ls.rm+rs.lm);
35     u.lm = max(ls.lm,ls.sum+rs.lm); u.rm = max(rs.rm,rs.sum+ls.rm);
36     u.all = max(u.all,max(u.lm,u.rm));
37 }
38
39 void Build(int u,int l,int r) {
40     if(l == r) {in(a); t[u].lm = t[u].rm = t[u].all = t[u].sum = a; return;}
41     int mid = (l+r)>>1;
42     Build(u<<1,l,mid); Build(u<<1|1,mid+1,r);
43     P_up(t[u],t[u<<1],t[u<<1|1]);
44 }
45
46 void A(int u,int l,int r,int x,int k) {
47     if(l == r) {t[u].all = t[u].lm = t[u].rm = t[u].sum = k; return;}
48     int mid = (l+r)>>1;
49     if(x <= mid) A(u<<1,l,mid,x,k); else A(u<<1|1,mid+1,r,x,k);
50     P_up(t[u],t[u<<1],t[u<<1|1]);
51 }
52
53 node Q(int u,int l,int r,int x,int y) {
54     if(x <= l && y >= r) {return t[u];}//important
55     int mid = (l+r)>>1;
56     if(y <= mid) return Q(u<<1,l,mid,x,y);
57     else if(x > mid) return Q(u<<1|1,mid+1,r,x,y);
58     else {
59         node _u,ls,rs;
60         ls = Q(u<<1,l,mid,x,mid); rs = Q(u<<1|1,mid+1,r,mid+1,y);
61         P_up(_u,ls,rs);
62         return _u;
63     }
64 }
65
66 int main() {
67     int op,x,y; in(n);
68     Build(1,1,n);
69     in(q);
70     while(q--) {
71         in(op); in(x); in(y);
72         if(!op) A(1,1,n,x,y);
73         else out(Q(1,1,n,x,y).all),putchar(‘\n‘);
74     }
75     return 0;
76 }

原文地址:https://www.cnblogs.com/mzg1805/p/11444574.html

时间: 2024-08-30 13:22:48

模板——线段树维护最大子段和 SP1716 GSS3 - Can you answer these queries III的相关文章

线段树 SP1716 GSS3 - Can you answer these queries III

SP1716 GSS3 - Can you answer these queries III 题意翻译 n 个数,q 次操作 操作0 x y把A_xAx 修改为yy 操作1 l r询问区间[l, r] 的最大子段和 依旧是维护最大子段和,还是再敲一遍比较好. code: #include<iostream> #include<cstdio> #define ls(o) o<<1 #define rs(o) o<<1|1 using namespace std

SP1716 GSS3 - Can you answer these queries III 线段树

题目传送门:SP1043 GSS1 - Can you answer these queries I 更好的阅读体验 动态维护子段和最大值 前置知识 静态维护子段和最大值:SP1043 GSS1 - Can you answer these queries I 题解传送 题解: 提供结构体指针线段树写法: 设\(l\)为区间左端点, \(r\)为区间右端点: \(ls\)为以\(l\)为左端点的最大子段和, \(rs\)为以\(r\)为右端点的最大子段和; \(sum\)为区间和, \(val\

SP1716 GSS3 - Can you answer these queries III - 动态dp,线段树

GSS3 Description 动态维护最大子段和,支持单点修改. Solution 设 \(f[i]\) 表示以 \(i\) 为结尾的最大子段和, \(g[i]\) 表示 \(1 \sim i\) 的最大子段和,那么 \[f[i] = max(f[i - 1] + a[i], a[i])\] \[g[i] = max(g[i - 1], f[i])\] 发现只跟前一项有关.我们希望使用矩阵乘法的思路,但是矩阵乘法通常只能适用于递推问题.因此我们引入广义矩阵乘法. 矩阵乘法问题可分治的原因在于

SP1716 GSS3 - Can you answer these queries III

题意:给定n个数a[1]~a[n],有q次操作. 操作 0 x y:把第a[x]修改为y: 操作 1 x y:询问x到y的的最大子段和. 输入:第一行:一个正整数n,表示有n个整数: 第二行:n个整数,表示数列: 第三行:一个正整数q,表示有q个询问: 第4~q+3行:每行三个数p,x,y,表示三种操作. 输出:对于每一个种类为1的询问,输出最大子段和. 输入样例: 41 2 3 441 1 30 3 -31 2 41 3 3 输出样例: 64-3 解析:用线段树进行维护,记录下每一段的和(su

SP1716 GSS3 - Can you answer these queries III(单点修改,区间最大子段和)

题意翻译 nnn 个数, qqq 次操作 操作0 x y把 AxA_xAx? 修改为 yyy 操作1 l r询问区间 [l,r][l, r][l,r] 的最大子段和 题目描述 You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations: modify the i-th ele

SPOJ GSS3 Can you answer these queries III (线段树)

题目大意: 求区间最大子区间的和. 思路分析: 记录左最大,右最大,区间最大. 注意Q_L  和 Q_R  就好. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 55555 using na

题解 SP1716 【GSS3 - Can you answer these queries III】

\[ Preface \] 没有 Preface. \[ Description \] 维护一个长度为 \(n\) 的数列 \(A\) ,需要支持以下操作: 0 x y 将 \(A_x\) 改为 \(y\) . 1 x y 求 \(\max\limits_{x \leq l \leq r \leq y}{\sum_{i=l}^rA[i]}\) . \[ Solution \] 区间最大子段和 是一个非常经典的问题. 对于 整体最大子段和 来说,一般有 \(O(n)\) 的 贪心 和 分治 做法,

SPOJ GSS3 Can you answer these queries III ——线段树

[题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set> #include <queue> #include <string> #include <iostream&

数据结构(线段树):SPOJ GSS3 - Can you answer these queries III

GSS3 - Can you answer these queries III You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations: modify the i-th element in the sequence or for given x y print max{