Can you answer these queries III

Time Limit: 2000ms
Memory Limit: 262144KB
This problem will be judged on SPOJ. Original ID: GSS3
64-bit integer IO format: %lld      Java class name: Main

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
 

Source

 
解题:带修改的最大字段和
SPOJ GSS3 Can you answer these queries III_javaSPOJ GSS3 Can you answer these queries III_线段树_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 50010;
 4 struct node {
 5     int lt,rt,lsum,rsum,sum,msum;
 6 } tree[maxn<<2];
 7 inline void pushup(int v) {
 8     tree[v].sum = tree[v<<1].sum + tree[v<<1|1].sum;
 9     tree[v].lsum = max(tree[v<<1].lsum,tree[v<<1].sum + tree[v<<1|1].lsum);
10     tree[v].rsum = max(tree[v<<1|1].rsum,tree[v<<1|1].sum + tree[v<<1].rsum);
11     tree[v].msum = max(max(tree[v<<1].msum,tree[v<<1|1].msum),tree[v<<1].rsum + tree[v<<1|1].lsum);
12 }
13 void build(int lt,int rt,int v) {
14     tree[v].lt = lt;
15     tree[v].rt = rt;
16     if(lt == rt) {
17         scanf("%d",&tree[v].sum);
18         tree[v].msum = tree[v].lsum = tree[v].rsum = tree[v].sum;
19         return;
20     }
21     int mid = (lt + rt)>>1;
22     build(lt,mid,v<<1);
23     build(mid + 1,rt,v<<1|1);
24     pushup(v);
25 }
26 void update(int pos,int val,int v) {
27     if(tree[v].lt == tree[v].rt) {
28         tree[v].sum = (tree[v].rt - tree[v].lt + 1)*val;
29         tree[v].lsum = tree[v].rsum = tree[v].msum = max(tree[v].sum,val);
30         return;
31     }
32     if(pos <= tree[v<<1].rt) update(pos,val,v<<1);
33     if(pos >= tree[v<<1|1].lt) update(pos,val,v<<1|1);
34     pushup(v);
35 }
36 node query(int lt,int rt,int v) {
37     if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v];
38     int mid = (tree[v].lt + tree[v].rt)>>1;
39     if(rt <= mid) return query(lt,rt,v<<1);
40     if(lt > mid) return query(lt,rt,v<<1|1);
41     node a = query(lt,rt,v<<1);
42     node b = query(lt,rt,v<<1|1);
43     node c;
44     c.sum = a.sum + b.sum;
45     c.lsum = max(a.lsum,a.sum + b.lsum);
46     c.rsum = max(b.rsum,b.sum + a.rsum);
47     c.msum = max(max(a.msum,b.msum),a.rsum + b.lsum);
48     return c;
49 }
50 int main() {
51     int n,m,x,y,op;
52     while(~scanf("%d",&n)) {
53         build(1,n,1);
54         scanf("%d",&m);
55         while(m--) {
56             scanf("%d%d%d",&op,&x,&y);
57             if(op) {
58                 node d = query(x,y,1);
59                 printf("%d\n",max(max(d.sum,d.msum),max(d.lsum,d.rsum)));
60             } else update(x,y,1);
61         }
62     }
63     return 0;
64 }
View Code

 

夜空中最亮的星,照亮我前行