1. 程式人生 > >Contest Hunter 4301 Can you answer on these queries III【線段樹】

Contest Hunter 4301 Can you answer on these queries III【線段樹】

描述

給定長度為N的數列A,以及M條指令 (N≤500000, M≤100000),每條指令可能是以下兩種之一: “2 x y”,把 A[x] 改成 y。 “1 x y”,查詢區間 [x,y] 中的最大連續子段和,即 max(x≤l≤r≤y)⁡ { ∑(i=l~r) A[i] }。 對於每個詢問,輸出一個整數表示答案。

輸入格式

第一行兩個整數N,M 第二行N個整數Ai 接下來M行每行3個整數k,x,y,k=1表示查詢(此時如果x>y,請交換x,y),k=2表示修改

輸出格式

對於每個詢問輸出一個整數表示答案。

對於每個節點,我們維護四個資訊sum,mx,mxl,mxrsum,mx,mxl,mxr

sumsum表示區間和,

mxmx表示區間最大連續子段和

mxlmxl表示緊靠左端的最大連續子段和

mxrmxr表示緊靠右端的最大連續子段和

則有: tr[p].sum=tr[lson].sum+tr[rson].sumtr[p].sum=tr[lson].sum+tr[rson].sum tr[p].mxl=max(tr[lson].mxl,tr[lson].sum+tr[rson].mxl)tr[p].mxl=max(tr[lson].mxl,tr[lson].sum+tr[rson].mxl)

tr[p].mxr=max(tr[rson].mxr,tr[rson].sum+tr[lson].mxr)tr[p].mxr=max(tr[rson].mxr,tr[rson].sum+tr[lson].mxr) tr[p].max=max(tr[lson].mx,tr[rson].mx,tr[lson].mxr+tr[rson].mxl)tr[p].max=max(tr[lson].mx,tr[rson].mx,tr[lson].mxr+tr[rson].mxl)

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define db double
#define sg string
#define ll long long
#define make make_pair
#define pll pair<ll,ll>
#define rel(i,x,y) for(ll i=(x);i<(y);i++)
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
#define res(i,x) for(ll i=head[x];i;i=nxt[i])
using namespace std;

const ll M=5e5+5; 
const ll N=2e6+6;
const ll Inf=1e18;
const db Eps=1e-10;

ll n,m,x,y,a[M];

struct node {
	ll l,r,sum;
	ll mx,mxl,mxr;
}tr[N];

#define lson (p<<1)
#define rson (p<<1|1)

inline ll read() {
	ll x=0;char ch=getchar();bool f=0;
	while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?-x:x;
}

void ini(node &tre,ll ret) {
	tre.sum=tre.mx=tre.mxl=tre.mxr=ret;
}

void pushup(ll p) {
	tr[p].sum=tr[lson].sum+tr[rson].sum;
	tr[p].mxl=max(tr[lson].mxl,tr[lson].sum+tr[rson].mxl);
	tr[p].mxr=max(tr[rson].mxr,tr[rson].sum+tr[lson].mxr);tr[p].mx=max(max(tr[lson].mx,tr[rson].mx),tr[lson].mxr+tr[rson].mxl);
}

void maketree(ll p,ll l,ll r) {
	tr[p].l=l,tr[p].r=r;ini(tr[p],a[l]);
	
	if(l<r) {
		ll mid=l+r>>1;
		maketree(lson,l,mid);
		maketree(rson,mid+1,r);pushup(p);
	}
}

void update(ll p) {
	if(tr[p].l==tr[p].r) {
		ini(tr[p],y);return ;
	}
	
	ll mid=tr[p].l+tr[p].r>>1;
	
	if(x<=mid) update(lson);
	else update(rson);pushup(p);
}

node getans(ll p) {
	if(x<=tr[p].l&&tr[p].r<=y) return tr[p];
	
	ll mid=tr[p].l+tr[p].r>>1;
	
	node a,b,c;ini(a,-Inf);ini(b,-Inf);
	
	c.sum=0;
	
	if(x<=mid) {
		a=getans(lson);c.sum+=a.sum;
	}
	
	if(mid<y) {
		b=getans(rson);c.sum+=b.sum;
	}
	
	c.mx=max(max(a.mx,b.mx),a.mxr+b.mxl);
	c.mxl=max(a.mxl,a.sum+b.mxl);c.mxr=max(b.mxr,b.sum+a.mxr);
	
	if(x>mid) c.mxl=max(c.mxl,b.mxl);
	
	if(y<=mid) c.mxr=max(c.mxr,a.mxr);
	
	return c;
}

int main() {
	n=read(),m=read();
	
	rep(i,1,n) a[i]=read();
	
	maketree(1,1,n);
	
	rep(i,1,m) {
		ll type=read();x=read(),y=read();
		
		if(type==1) {
			if(x>y) swap(x,y);
			printf("%lld\n",getans(1).mx);
		} else update(1);
	}
	
	return 0;
}