#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<cstring>
using namespace std;
const int N=50010;
int T,M,n,s,t,num,Max[N<<3],Min[N<<3];
char op[3];
void build()
{
for(int i=M+1; i<=M+n; i++)
scanf("%d",&Max[i]),Min[i]=Max[i];
for(int i=M; i>0; i--)
{
Max[i]=max(Max[i<<1],Max[i<<1|1]);
Max[i<<1]-=Max[i],Max[i<<1|1]-=Max[i];
Min[i]=min(Min[i<<1],Min[i<<1|1]);
Min[i<<1]-=Min[i],Min[i<<1|1]-=Min[i];
}
}
void update(int pos,int val)
{
int a;
Max[pos+M]+=val,Min[pos+M]+=val;
for(pos=pos+M; pos; pos>>=1)
{
a=max(Max[pos<<1],Max[pos<<1|1]);
Max[pos<<1]-=a,Max[pos<<1|1]-=a,Max[pos]+=a;
a=min(Min[pos<<1],Min[pos<<1|1]);
Min[pos<<1]-=a,Min[pos<<1|1]-=a,Min[pos]+=a;
}
}
void update(int s,int t,int val)
{
int a;
if(s==t)
{
update(s,val);
return ;
}
Max[s+M]+=val,Min[s+M]+=val;
Max[t+M]+=val,Min[t+M]+=val;
for(s=s+M,t=t+M; s^t^1; s>>=1,t>>=1)
{
if(~s&1) Max[s^1]+=val,Min[s^1]+=val;
if(t&1) Max[t^1]+=val,Min[t^1]+=val;
a=max(Max[s<<1],Max[s<<1|1]);
Max[s<<1]-=a,Max[s<<1|1]-=a,Max[s]+=a;
a=min(Min[s<<1],Min[s<<1|1]);
Min[s<<1]-=a,Min[s<<1|1]-=a,Min[s]+=a;
a=max(Max[t<<1],Max[t<<1|1]);
Max[t<<1]-=a,Max[t<<1|1]-=a,Max[t]+=a;
a=min(Min[t<<1],Min[t<<1|1]);
Min[t<<1]-=a,Min[t<<1|1]-=a,Min[t]+=a;
}
a=max(Max[t<<1],Max[t<<1|1]);
Max[t<<1]-=a,Max[t<<1|1]-=a,Max[t]+=a;
a=min(Min[t<<1],Min[t<<1|1]);
Min[t<<1]-=a,Min[t<<1|1]-=a,Min[t]+=a;
while(s)
{
a=max(Max[s<<1],Max[s<<1|1]);
Max[s<<1]-=a,Max[s<<1|1]-=a,Max[s]+=a;
a=min(Min[s<<1],Min[s<<1|1]);
Min[s<<1]-=a,Min[s<<1|1]-=a,Min[s]+=a;
s>>=1;
}
}
int getmax(int s,int t)
{
int L=0,R=0,res=0;
if(s==t)
{
while(s) res+=Max[s],s>>=1;
return res;
}
for(s=s+M,t=t+M; s^t^1; s>>=1,t>>=1)
{
L+=Max[s],R+=Max[t];
if(~s&1) L=max(L,Max[s^1]);
if(t&1) R=max(R,Max[t^1]);
}
res=max(L+Max[s],R+Max[t]);
while(s) res+=Max[s>>=1];
return res;
}
int getmin(int s,int t)
{
int L=0,R=0,res=0;
if(s==t)
{
while(s) res+=Max[s],s>>=1;
return res;
}
for(s=s+M,t=t+M; s^t^1; s>>=1,t>>=1)
{
L+=Min[s],R+=Min[t];
if(~s&1) L=min(L,Min[s^1]);
if(t&1) R=min(R,Min[t^1]);
}
res=min(L+Min[s],R+Min[t]);
while(s) res+=Min[s>>=1];
return res;
}
int main()
{
scanf("%d %d",&n,&T);
for(M=1; M<n; M<<=1);
M--,build();
while(T--)
{
scanf("%s%d%d",op,&s,&t);
if(op[0]=='Q') printf("%d\n",getmax(s,t)-getmin(s,t));
else scanf("%d",&num),update(s,t,num);
}
return 0;
}
ZKW 线段树区间修改,最值(差分
最新推荐文章于 2024-06-23 19:31:27 发布
本文介绍了一种使用线段树进行区间更新与查询最大最小值的高效算法实现。该方法适用于需要频繁更新区间内元素并查询区间最大最小值的应用场景,如动态规划、游戏开发等。文章通过具体的代码示例展示了如何构建线段树、更新区间元素及查询区间最大最小值的具体过程。
3790

被折叠的 条评论
为什么被折叠?



