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 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

Hint

Added by: Bin Jin
Date: 2007-08-03
Time limit: 0.330s
Source limit: 5000B
Memory limit: 1536MB
Cluster: Cube (Intel G860)
Languages: All except: C++ 5
Resource: own problem

单点修改,询问区间内最大连续字段和。

@TYVJ P1427 小白逛公园

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #define lc rt<<1
 8 #define rc rt<<1|1
 9 using namespace std;
10 const int mxn=100010;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
14     while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
15     return x*f;
16 }
17 int n,m;
18 int data[mxn];
19 struct node{
20     int mx;
21     int ml,mr;
22     int smm;
23 }t[mxn<<2],tmp0;
24 void push_up(int l,int r,int rt){
25     t[rt].smm=t[lc].smm+t[rc].smm;
26     t[rt].mx=max(t[lc].mx,t[rc].mx);
27     t[rt].mx=max(t[lc].mr+t[rc].ml,t[rt].mx);
28     t[rt].ml=max(t[lc].ml,t[lc].smm+t[rc].ml);
29     t[rt].mr=max(t[rc].mr,t[rc].smm+t[lc].mr);
30     return;
31 }
32 void Build(int l,int r,int rt){
33     if(l==r){t[rt].mx=t[rt].ml=t[rt].mr=data[l];t[rt].smm=data[l];return;}
34     int mid=(l+r)>>1;
35     Build(l,mid,lc);
36     Build(mid+1,r,rc);
37     push_up(l,r,rt);
38     return;
39 }
40 void change(int p,int v,int l,int r,int rt){
41     if(l==r){
42         if(p==l){t[rt].ml=t[rt].mr=t[rt].mx=t[rt].smm=v;}
43         return;
44     }
45     int mid=(l+r)>>1;
46     if(p<=mid)change(p,v,l,mid,lc);
47     else change(p,v,mid+1,r,rc);
48     push_up(l,r,rt);
49     return;
50 }
51 node query(int L,int R,int l,int r,int rt){
52 //    printf("%d %d %d %d %d\n",L,R,l,r,rt);
53     if(L<=l && r<=R){return t[rt];}
54     int mid=(l+r)>>1;
55     node res1;
56     if(L<=mid)res1=query(L,R,l,mid,lc);
57         else res1=tmp0;
58     node res2;
59     if(R>mid)res2=query(L,R,mid+1,r,rc);
60         else res2=tmp0;
61     node res={0};
62     res.smm=res1.smm+res2.smm;
63     res.mx=max(res1.mx,res2.mx);
64     res.mx=max(res.mx,res1.mr+res2.ml);
65     res.ml=max(res1.ml,res1.smm+res2.ml);
66     res.mr=max(res2.mr,res2.smm+res1.mr);
67     return res;
68 }
69 int main(){
70     n=read();
71     int i,j,x,y,k;
72     for(i=1;i<=n;i++)data[i]=read();
73     Build(1,n,1);
74     tmp0.ml=tmp0.mr=tmp0.mx=-1e9;tmp0.smm=0;
75     m=read();
76     for(i=1;i<=m;i++){
77         k=read();x=read();y=read();
78         if(k){
79             if(x>y)swap(x,y);
80             printf("%d\n",query(x,y,1,n,1).mx);
81         }
82         else change(x,y,1,n,1);
83     }
84     return 0;
85 }
时间: 2024-10-31 14:36:25

SPOJ GSS3 Can you answer these queries III的相关文章

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

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{

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&

线段树 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(单点修改,区间最大子段和)

题意翻译 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

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])\] 发现只跟前一项有关.我们希望使用矩阵乘法的思路,但是矩阵乘法通常只能适用于递推问题.因此我们引入广义矩阵乘法. 矩阵乘法问题可分治的原因在于

Spoj 1716 Can you answer these queries III 线段树 单点修改 区间求最大子段和

题目链接:点击打开链接 == 原来写1的时候已经把更新函数写好了.. #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <vector> #include <map> using namespace std; #define N 50050 #define Lso

spoj 1716 Can you answer these queries III(线段树)

和I相比有了单点更新,所以不能只记录一个前缀和,而是要在线段树上多维护一个sum,表示这个结点的区间和,然后其他的就和I一样了. #include <iostream>#include <cstring>#include <cstdio>using namespace std; const int N = 50001;int a[N]; struct Node { int l, r, sum; int maxl, maxr, maxn;} node[N <<