最大值(区间修改)
总时间限制: 10000ms
单个测试点时间限制: 1000ms
内存限制: 65536kB
描述
在N(1<=n<=100000)个数A1…An组成的序列上进行
M(1<=m<=100000)次操作,操作有两种:
(1)1 LR C:表示把A[L]到A[R]增加C(C的绝对值不超过10000);
(2)2 LR:询问A[L]到A[R]之间的最大值。
输入
第一行输入N(1<=N<=100000),表示序列的长度,接下来N行输入原始序列;接下来一行输入M(1<=M<=100000)表示操作的次数,接下来M行,每行为1 L R C或2 L R
输出
对于每个操作(2)输出对应的答案。
样例输入
5
1
2
3
4
5
3
2 1 4
1 1 3 3
2 3 5
样例输出
4
6
提示
保证序列中的所有的数都在longint范围内
AC代码
#include<bits/stdc++.h> //最大值(区间修改)
#define MAXN 100005
using namespace std;
int t[MAXN][2],mx[MAXN],fa[MAXN],lazy[MAXN],a[MAXN],st[MAXN];
int n,m;
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0' || '9'<ch){
if(ch=='-') f=-1;
ch=getchar();
}
while('0'<=ch && ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void update(int x){
mx[x]=max(a[x],max(mx[t[x][0]],mx[t[x][1]]));
}
void clear(int x){
if(t[x][0]){
a[t[x][0]]+=lazy[x];
mx[t[x][0]]+=lazy[x];
lazy[t[x][0]]+=lazy[x];
}
if(t[x][1]){
a[t[x][1]]+=lazy[x];
mx[t[x][1]]+=lazy[x];
lazy[t[x][1]]+=lazy[x];
}
lazy[x]=0;
}
void jc(int x){
st[0]=0;
while(x) st[++st[0]]=x,x=fa[x];
while(st[0]) clear(st[st[0]--]);
}
int jc__(int x){
return t[fa[x]][1]==x;
}
void jj(int x) {
int y=fa[x],k=jc__(x);
t[y][k]=t[x][!k];
if (t[x][!k])fa[t[x][!k]]=y;
fa[x]=fa[y];
if (fa[y])t[fa[y]][jc__(y)]=x;
t[x][!k]=y;
fa[y]=x;
update(y),update(x);
}
void ll(int x,int y) {
jc(x);
while(fa[x]!=y){
if(fa[fa[x]]!=y){
if (jc__(x)==jc__(fa[x]))jj(fa[x]);
else jj(x);
}
jj(x);
}
}
int main(){
n=read();
mx[0]=-1e9;
for (int i=1;i<=n;i++)a[i+1]=read(),fa[i]=i+1,t[i+1][0]=i,update(i+1);
fa[n+1]=n+2,t[n+2][0]=n+1,update(n+2);
m=read();
while (m--){
int z=read(),x=read()+1,y=read()+1;
ll(x-1,0),ll(y+1,x-1);
if(z==1){
int temp=read();
a[t[y+1][0]]+=temp;
mx[t[y+1][0]]+=temp;
lazy[t[y+1][0]]+=temp;
}
else printf("%d\n",mx[t[y+1][0]]);
}
return 0;
}