数据结构(线段树):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{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.

Input

The first line of input contains an integer N. The following line contains N integers, representing the sequence A1..AN.
The third line contains an integer M. The next M lines contain the operations in following form:
0 x y: modify Ax into y (|y|<=10000).
1 x y: print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.

Output

For each query, print an integer as the problem required.

Example

Input:
4
1 2 3 4
4
1 1 3
0 3 -3
1 2 4
1 3 3

Output:
6
4
-3
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=50010;
 6 const int INF=1000000000;
 7 int n,Q,a[maxn];
 8
 9 struct Node{
10     int lx,rx,mx,sum;
11     Node(int _lx=-INF,int _rx=-INF,int _mx=-INF){
12         lx=_lx;rx=_rx;mx=_mx;
13     }
14 }T[maxn<<2];
15
16 void Push_up(Node &x,Node l,Node r){
17     x.sum=l.sum+r.sum;
18     x.lx=max(l.lx,l.sum+r.lx);
19     x.rx=max(r.rx,r.sum+l.rx);
20     x.mx=max(max(l.mx,r.mx),l.rx+r.lx);
21 }
22
23 void Build(int x,int l,int r){
24     if(l==r){
25         T[x].lx=T[x].rx=max(a[l],0);
26         T[x].mx=T[x].sum=a[l];
27         return;
28     }
29     int mid=(l+r)>>1;
30     Build(x<<1,l,mid);
31     Build(x<<1|1,mid+1,r);
32     Push_up(T[x],T[x<<1],T[x<<1|1]);
33 }
34
35 void Modify(int x,int l,int r,int g){
36     if(l==r){
37         T[x].lx=T[x].rx=max(a[l],0);
38         T[x].mx=T[x].sum=a[l];
39         return;
40     }
41     int mid=(l+r)>>1;
42     if(mid>=g)Modify(x<<1,l,mid,g);
43     else Modify(x<<1|1,mid+1,r,g);
44     Push_up(T[x],T[x<<1],T[x<<1|1]);
45 }
46
47 Node Query(int x,int l,int r,int a,int b){
48     if(l>=a&&r<=b)
49         return T[x];
50     int mid=(l+r)>>1;
51     Node L,R,ret;
52     if(mid>=a)L=Query(x<<1,l,mid,a,b);
53     if(mid<b)R=Query(x<<1|1,mid+1,r,a,b);
54     Push_up(ret,L,R);
55     return ret;
56 }
57
58 int main(){
59     scanf("%d",&n);
60     for(int i=1;i<=n;i++)
61         scanf("%d",&a[i]);
62     Build(1,1,n);
63     scanf("%d",&Q);
64     int tp,x,y;
65     while(Q--){
66         scanf("%d%d%d",&tp,&x,&y);
67         if(!tp)
68             a[x]=y,Modify(1,1,n,x);
69         else
70             printf("%d\n",Query(1,1,n,x,y).mx);
71     }
72     return 0;
73 }
水题。
时间: 2024-10-13 02:59:50

数据结构(线段树):SPOJ 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

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

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

Time Limit: 330MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description 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

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】

\[ 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)\) 的 贪心 和 分治 做法,

GSS3 - Can you answer these queries III

题意翻译 nnn 个数, qqq 次操作 操作0 x y把 AxA_xAx? 修改为 yyy 操作1 l r询问区间 [l,r][l, r][l,r] 的最大子段和 感谢 @Edgration 提供的翻译 题目描述 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:

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