线段树区间修改 + 区间极值查询
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct node{
int l;
int r;
int f;
long long w;
}tree[100000];
int T,n,m,x,y,val;
long long ans;
void build(int k,int l,int r)
{
tree[k].l = l;
tree[k].r = r;
if(l == r)
{
scanf("%lld",&tree[k].w);
return ;
}
int m = (l + r)>> 1;
build(k<<1,l,m);
build(k<<1|1,m+1,r);
tree[k].w = max(tree[k<<1].w, tree[k<<1|1].w);
}
void down(int k)
{
tree[k<<1].f += tree[k].f;
tree[k<<1|1].f += tree[k].f;
tree[k<<1].w += (tree[k<<1].r - tree[k<<1].l + 1) *tree[k].f;
tree[k<<1|1].w += (tree[k<<1|1].r - tree[k<<1|1].l + 1) *tree[k].f;
tree[k].f = 0;
}
void update(int k)
{
if(x <= tree[k].l && y>= tree[k].r)
{
tree[k].w += val;
tree[k].f += val;
return ;
}
if(tree[k].f) down(k);
int m =(tree[k].l + tree[k].r)>>1;
if(x<=m) update(k<<1);
if(y>m) update(k<<1|1);
tree[k].w = max(tree[k<<1].w , tree[k<<1|1].w);
}
void ask(int k)
{
if(tree[k].l >= x && tree[k].r <=y)
{
ans = max(tree[k].w,ans);
return ;
}
if(tree[k].f) down(k);
int m =(tree[k].l + tree[k].r)>>1;
if(x<=m) ask(k<<1);
if(y>m) ask(k<<1|1);
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int op;
scanf("%d",&op);
if(op == 1)
{
scanf("%d%d%d",&x,&y,&val);
update(1);
}
else {
scanf("%d%d",&x,&y);
ans = 0;
ask(1);
printf("%lld\n",ans);
}
}
}
}
线段树区间修改 + 区间求和
#include<iostream>
#include<cstdio>
using namespace std;
struct No{
int l;
int r;
int w;
int f;
}tree[200000*4+10];
int n,m,op,x,y,val;
long long ans;
void build(int k,int l,int r)
{
tree[k].l = l;
tree[k].r = r;
if(l == r)
{
scanf("%d",&tree[k].w);
return ;
}
int m = (l+r)>>1;
build(k<<1,l,m);
build(k<<1|1,m+1,r);
tree[k].w = tree[k<<1].w + tree[k<<1|1].w;
}
void down(int k)
{
tree[k<<1].f += tree[k].f;
tree[k<<1|1].f += tree[k].f;
tree[k<<1].w +=(tree[k<<1].r - tree[k<<1].l +1)*tree[k].f;
tree[k<<1|1].w += (tree[k<<1|1].r - tree[k<<1|1].l +1)*tree[k].f;
tree[k].f = 0;
}
void add(int k)
{
if(tree[k].l >=x&&tree[k].r<=y)
{
tree[k].w += val;
tree[k].f += val;
return ;
}
if(tree[k].f) down(k);
int m = (tree[k].l + tree[k].r)>>1;
if(x<=m) add(k<<1);
if(y>m) add(k<<1|1);
tree[k].w = tree[k<<1].w + tree[k<<1|1].w;
}
void ask(int k)
{
if(tree[k].l>=x&&tree[k].r<=y)
{
ans += tree[k].w;
return ;
}
if(tree[k].f) down(k);
int m = (tree[k].l + tree[k].r)>>1;
if(x<=m) ask(k<<1);
if(y>m) ask(k<<1|1);
}
int main()
{
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
while(m--)
{
scanf("%d",&op);
if(op == 1)
{
scanf("%d%d%d",&x,&y,&val);
add(1);
}
else {
scanf("%d%d",&x,&y);
ans = 0;
ask(1);
printf("%lld\n",ans);
}
}
return 0;
}