区间查改
题目链接:YbtOJ
解题思路
线段树模板题。
code
#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
int n,q;
int a[1000010];
struct abc{
int x,y;
int s,lzy;
}tree[4000010];
int build(int now,int x,int y)
{
tree[now].x=x;
tree[now].y=y;
if(x==y)
{
tree[now].s=a[x];
return tree[now].s;
}
int mid=(x+y)/2;
int l=build(now*2,x,mid);
int r=build(now*2+1,mid+1,y);
return tree[now].s=l+r;
}
void down(int now)
{
if(!tree[now].lzy)
return;
tree[now*2].lzy+=tree[now].lzy;
tree[now*2+1].lzy+=tree[now].lzy;
tree[now*2].s+=(tree[now*2].y-tree[now*2].x+1)*tree[now].lzy;
tree[now*2+1].s+=(tree[now*2+1].y-tree[now*2+1].x+1)*tree[now].lzy;
tree[now].lzy=0;
}
void add(int now,int l,int r,int g)
{
if(tree[now].x>=l&&tree[now].y<=r)
{
tree[now].s+=(tree[now].y-tree[now].x+1)*g;
tree[now].lzy+=g;
return;
}
down(now);
int mid=(tree[now].x+tree[now].y)/2;
if(r<=mid)
add(now*2,l,r,g);
else if(l>mid)
add(now*2+1,l,r,g);
else
add(now*2,l,r,g),add(now*2+1,l,r,g);
tree[now].s=tree[now*2].s+tree[now*2+1].s;
}
int fd(int now,int l,int r)
{
if(tree[now].x>=l&&tree[now].y<=r)
return tree[now].s;
int mid=(tree[now].x+tree[now].y)/2;
down(now);
if(r<=mid)
return fd(now*2,l,r);
else if(l>mid)
return fd(now*2+1,l,r);
else
return fd(now*2,l,r)+fd(now*2+1,l,r);
}
signed main()
{
cin>>n>>q;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
while(q--)
{
int t,l,r;
scanf("%lld%lld%lld",&t,&l,&r);
if(t==1)
{
int g;
scanf("%lld",&g);
add(1,l,r,g);
}
else
cout<<fd(1,l,r)<<endl;
}
}