#include <iostream>
#include <bits/stdc++.h>
#define maxn 800005
using namespace std;
typedef long long ll;
ll tree[maxn]={0};
ll lazy[maxn]={0};
ll a[200005]={0};
int n;
void pushup(int rt)
{
tree[rt]=max(tree[rt*2],tree[rt*2+1]);
}
void buildtree(int l,int r,int rt)
{
if(l==r)
{
tree[rt]=a[l];
return;
}
int mid=(l+r)/2;
buildtree(l,mid,rt*2);
buildtree(mid+1,r,rt*2+1);
pushup(rt);
}
void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt*2]+=lazy[rt];
lazy[rt*2+1]+=lazy[rt];
tree[rt*2]+=lazy[rt];
tree[rt*2+1]+=lazy[rt];
lazy[rt]=0;
}
}
void add(int l,int r,int L,int R,int rt,int val)
{
if(L<=l&&R>=r)
{
lazy[rt]+=val;
tree[rt]+=val;
return;
}
if(lazy[rt]) pushdown(rt);
int mid=(l+r)/2;
if(L<=mid) add(l,mid,L,R,rt*2,val);
if(R>mid) add(mid+1,r,L,R,rt*2+1,val);
pushup(rt);
}
ll query(int l,int r,int L,int R,int rt)
{
if(L<=l&&R>=r)
{
return tree[rt];
}
int mid=(l+r)/2;
pushdown(rt);
ll ret=1e9;
if(L<=mid) ret=query(l,mid,L,R,rt*2);
if(R>mid) ret=max(ret,query(mid+1,r,L,R,rt*2+1));
return ret;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
buildtree(1,n,1);
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{ char c;
scanf("%c",&c);
if(c=='a')
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
add(1,n,x,y,1,val);
}
else if(c=='q')
{
int x,y;
scanf("%d%d",&x,&y);
cout<<query(1,n,x,y,1)<<endl;
}
}
return 0;
}
RMQ操作。
#include <bits/stdc++.h>
typedef long long ll;
const int MAXN=401000;
using namespace std;
ll mx[MAXN]={0};
ll a[MAXN]={0};
ll lazy[MAXN]={0};
void pushup(int rt)
{
mx[rt]=mx[rt*2]+mx[rt*2+1];
}
void buildtree(int l,int r,int rt)
{ lazy[rt]=0;
if(l==r)
{
mx[rt]=a[l];
return;
}
int mid=(l+r)/2;
buildtree(l,mid,rt*2);
buildtree(mid+1,r,rt*2+1);
pushup(rt);
}
void pushdown(int rt,int le,int ri)
{
if(lazy[rt])
{
lazy[rt*2]+=lazy[rt];
lazy[rt*2+1]+=lazy[rt];
mx[rt*2]+=lazy[rt]*le;
mx[rt*2+1]+=lazy[rt]*ri;
lazy[rt]=0;
}
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
mx[rt]+=1ll*val*(r-l+1);
lazy[rt]+=val;
return ;
}
int mid=(l+r)/2;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid) update(L,R,val,l,mid,rt*2);
if(R>mid) update(L,R,val,mid+1,r,rt*2+1);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return mx[rt];
}
int mid=(l+r)/2;
pushdown(rt,mid-l+1,r-mid);
ll ret=0;
if(L<=mid) ret=ret+query(L,R,l,mid,rt*2);
if(R>mid) ret=ret+query(L,R,mid+1,r,rt*2+1);
return ret;
}
int main()
{
int n,m;
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;++i)
{
//scanf("%lld",&a[i]);
cin>>a[i];
}
buildtree(1,n,1);
for(int i=1;i<=m;++i)
{
char c;
int x,y;
cin>>c>>x>>y;
if(c=='Q')
{
cout<<query(x,y,1,n,1)<<endl;
}
else
{
int val;
cin>>val;
update(x,y,val,1,n,1);
}
}
return 0;
}
区间修改/求和。