Given the number of columns of length N A, and M instructions, each instruction may be either of the following:
1, "1 xy", the query interval [x, y] is the maximum continuous and sub-segment, i.e. m A X X ≤ L ≤ R & lt ≤ Y maxx≤l≤r≤y { [Sigma R & lt I = L A [ I ] Σi = lrA [i]}.
2, "2 xy", the A [x] into y.
For each query command, output a integer answer.
Input Format
The first line of two integers N, M.
The second row of the N integers A [i].
Next, 3 M lines each integers k, x, y, k = 1 indicates that the query (in this case, if x> y, swap the x, y), k = 2 represents a modification.
Output Format
For each query command output represents an integer answer.
Each answer per line.
data range
N≤500000,M≤100000N≤500000,M≤100000
Sample input:
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 3 2
Sample output:
2
-1
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<cmath> const int maxn=5e5+5; typedef long long ll; using namespace std; struct node { int l,r; ll sum,suml,sumr,summax; }tree[maxn<<2]; void pushup(int m) { tree[m].sum=(tree[m<<1].sum+tree[m<<1|1].sum); tree[m].summax=max(max(tree[m<<1].summax,tree[m<<1|1].summax),tree[m<<1].sumr+tree[m<<1|1].suml); tree[m].suml=max(tree[m<<1].suml,tree[m<<1].sum+tree[m<<1|1].suml); tree[m].sumr=max(tree[m<<1|1].sumr,tree[m<<1].sumr+tree[m<<1|1].sum); } void build(int m,int l,int r) { tree[m].l=l; tree[m].r=r; if(l==r) { scanf("%lld",&tree[m].sum); tree[m].summax=tree[m].sum; tree[m].suml=tree[m].sum; tree[m].sumr=tree[m].sum; return ; } int mid=(l+r)>>1; build(m<<1,l,mid); build(m<<1|1,mid+1,r); pushup(m); } void update(int m,int pos,ll val) { if(tree[m].l==tree[m].r&&tree[m].l==pos) { tree[m].sum=val; tree[m].summax=tree[m].sum; tree[m].suml=tree[m].sum; tree[m].sumr=tree[m].sum; return ; } int mid=(tree[m].l+tree[m].r)>>1; if(pos<=mid) { update(m<<1,pos,val); } else { update(m<<1|1,pos,val); } pushup(m); } node query(int m,int l,int r) { if(tree[m].l==l&&tree[m].r==r) { return tree[m]; } int mid=(tree[m].l+tree[m].r)>>1; if(r<=mid) { return query(m<<1,l,r); } else if(l>mid) { return query(m<<1|1,l,r); } else { node treel,treer,temp; treel=query(m<<1,l,mid); treer=query(m<<1|1,mid+1,r); temp.sum=treel.sum+treer.sum; temp.summax=max(max(treel.summax,treer.summax),treel.sumr+treer.suml); temp.suml=max(treel.suml,treel.sum+treer.suml); temp.sumr=max(treer.sumr,treer.sum+treel.sumr); return temp; } } int main() { int n,q; cin>>n>>q; build(1,1,n); int op,l,r; while(q--) { scanf("%d",&op); if(op==1) { scanf("%d%d",&l,&r); if(l>r) { swap(l,r); } printf("%lld\n",query(1,l,r).summax); } else { scanf("%d%d",&l,&r); update(1,l,r); } } return 0; }