Description
在N(1<=N<=100000)个数A1…An组成的序列上进行M(1<=M<=100000)次操作,操作有两种:
(1)1 L R C:表示把A[L]到A[R]增加C(C的绝对值不超过10000);
(2)2 L R:询问A[L]到A[R]之间的最大值。
Input
第一行输入N(1<=N<=100000),表示序列的长度,接下来N行输入原始序列;接下来一行输入M(1<=M<=100000)表示操作的次数,接下来M行,每行为1 L R C或2 L R
Output
对于每个操作(2)输出对应的答案。
Sample Input
5
1
2
3
4
5
3
2 1 4
1 1 3 3
2 3 5
Sample Output
4
6
Data Constraint
Hint
【限制】
保证序列中的所有的数都在longint范围内
Solution
直接线段树+区间修改即可。
Code1
#include<cstdio>
using namespace std;
long long a[100020],f[500020],g[500020],ans,z;
int n,m,k,x,y;
int max(long long a,long long b){
if (a>b) return a;
else return b;
}
void add(int x,int l,int r){
if(!g[x]) return;
if(l!=r){g[x*2]+=g[x];g[x*2+1]+=g[x];f[x*2]+=g[x];f[x*2+1]+=g[x];}
g[x]=0;
}
void build(int x,int l,int r){
int m;
if (l==r) f[x]=a[l];
else{
m=(l+r)/2;
build(x*2,l,m);build(x*2+1,m+1,r);
f[x]=max(f[x*2],f[x*2+1]);
}
}
void change(int x,int s,int t,int l,int r,long long k){
if (l==s&&t==r) {g[x]+=k;f[x]+=k;}
else{
add(x,s,t);
int m=(s+t)/2;
if (r<=m) change(x*2,s,m,l,r,k);
else if (l>m) change(x*2+1,m+1,t,l,r,k);
else{
change(x*2,s,m,l,m,k);
change(x*2+1,m+1,t,m+1,r,k);
}
f[x]=max(f[x*2],f[x*2+1]);
}
}
void find(int x,int s,int t,int l,int r){
int m;
if ((s==l)and(t==r)) ans=max(ans,f[x]);
else{
add(x,s,t);
m=(s+t)/2;
if (r<=m) find(x*2,s,m,l,r);
else if (l>m) find(x*2+1,m+1,t,l,r);
else{
find(x*2,s,m,l,m);
find(x*2+1,m+1,t,m+1,r);
}
}
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
scanf("%d",&m);
for (int i=1;i<=m;i++){
scanf("%d%d%d",&k,&x,&y);
if (k==1){
scanf("%lld",&z);
change(1,1,n,x,y,z);
}
else{
ans=-2147483647;
find(1,1,n,x,y);
printf("%lld\n",ans);
}
}
return 0;
}
Code2
uses math;
var
i,j,n,m,s,x,y,z,w:longint;
f,a,c:array[0..310000]of longint;
procedure change(x,y,l,r,k,v:longint);
var m:longint;
begin
if (x=l)and(y=r) then
begin
inc(c[v],k); inc(f[v],k);
end else begin
inc(f[v*2],c[v]); inc(c[v*2],c[v]);
inc(f[v*2+1],c[v]); inc(c[v*2+1],c[v]);
c[v]:=0; m:=(x+y)div 2;
if r<=m then change(x,m,l,r,k,v*2)
else begin
if l>m then change(m+1,y,l,r,k,v*2+1)
else begin
change(x,m,l,m,k,v*2);
change(m+1,y,m+1,r,k,v*2+1);
end;
end; f[v]:=max(f[v*2],f[v*2+1]);
end;
end;
procedure tree(l,r,x:longint);
var mid:longint;
begin
if l=r then f[x]:=a[l]
else begin
mid:=(l+r)div 2;
tree(l,mid,x*2); tree(mid+1,r,x*2+1);
f[x]:=max(f[2*x],f[2*x+1]);
end;
end;
procedure find(x,y,l,r,v:longint);
var m:longint;
begin
if (x=l)and(y=r) then s:=max(s,f[v])
else begin
inc(f[v*2],c[v]); inc(c[v*2],c[v]);
inc(f[v*2+1],c[v]); inc(c[v*2+1],c[v]);
c[v]:=0; m:=(x+y)div 2;
if r<=m then find(x,m,l,r,v*2)
else begin
if l>m then find(m+1,y,l,r,v*2+1)
else begin
find(x,m,l,m,v*2);
find(m+1,y,m+1,r,v*2+1);
end;
end;
end;
end;
begin
readln(n);
for i:=1 to n do readln(a[i]);
tree(1,n,1); readln(m);
for i:=1 to m do begin
read(z);
if z=1 then
begin
readln(x,y,w);
change(1,n,x,y,w,1);
end else begin
readln(x,y); s:=-maxlongint;
find(1,n,x,y,1); writeln(s);
end;
end;
end.
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/81914293