Contest Hunter 4301 Can you answer on these queries III【線段樹】
阿新 • • 發佈:2018-12-17
描述
給定長度為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表示修改
輸出格式
對於每個詢問輸出一個整數表示答案。
對於每個節點,我們維護四個資訊
表示區間和,
表示區間最大連續子段和
表示緊靠左端的最大連續子段和
表示緊靠右端的最大連續子段和
則有:
#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;
}