线段树模板求助
查看原帖
线段树模板求助
210719
Violet___Evergarden楼主2021/9/10 21:48

rt

#include <iostream>
#define int long long
using namespace std;
const int kMaxN=1e5+1;
int a[kMaxN];
struct XDS
{
  int l,r;//每个节点的左儿子和右二字
  int z,add;
}tr[kMaxN*4];
int n,m;
void Build(int where,int le,int ri)//建树
{
  tr[where].l=le;
  tr[where].r=ri;
  if(le==ri)
  {
    tr[where].z=a[le];
    return;
  }
  int mid=(le+ri)/2;
  Build(where*2,le,mid);//建左儿子和右二字
  Build(where*2+1,mid+1,ri);
  tr[where].z=tr[where*2].z+tr[where*2+1].z;
}
void Solve(int where)//懒标记处理
{
  if(tr[where].add==0)
  {
    return;
  }
  tr[where*2].z+=tr[where].add*(tr[where*2].r-tr[where*2].l+1);
  tr[where*2+1].z=tr[where].add*(tr[where*2+1].r-tr[where*2+1].l+1);
  tr[where*2].add+=tr[where].add;
  tr[where*2+1].add+=tr[where].add;
  tr[where].add=0;
}
void Update(int where,int le,int ri,int k)//区间修改
{
  if(tr[where].l>=le&&tr[where].r<=ri)
  {
    tr[where].z+=k*(tr[where].r-tr[where].l+1);
    tr[where].add+=k;
    return;
  }
  Solve(where);
  int mid=(tr[where].r+tr[where].l)/2;
  if(mid>=le)
  {
    Update(where*2,le,mid,k);
  }
  if(mid<ri)
  {
    Update(where*2+1,mid+1,ri,k);
  }
  tr[where].z+=tr[where*2].z+tr[where*2+1].z;
}
int Get(int where,int le,int ri)//区间查询
{
  //cout<<where<<" "<<le<<" "<<ri<<"\n";
  if(tr[where].l>=le&&tr[where].r<=ri)
  {
    return tr[where].z;
  }
  Solve(where);
  int sum=0;
  int mid=(tr[where].l+tr[where].r)/2;
  if(mid>=le)
  {
    sum+=Get(where*2,le,mid);
  }
  if(mid<ri)
  {
    sum+=Get(where*2+1,mid+1,ri);
  }
  return sum;
}
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
  cin>>a[i];
}
Build(1,1,n);
for(int i=1;i<=m;i++)
{
  int a;
  cin>>a;
  if(a==1)
  {
    int x,y,k;
    cin>>x>>y>>k;
    Update(1,x,y,k);
  }
  else
  {
    int x,y;
    cin>>x>>y;
    cout<<Get(1,x,y)<<"\n";
  }
}
return 0;
}
2021/9/10 21:48
加载中...