线段树板子
1.ls和rs
int ls(int x)
{
return x<<1;
}
int rs(int x)
{
return x<<1|1;
}
2.build建树函数
void build(int p,int l,int r)
{
if(l==r)
{
ans[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
ans[p]=ans[ls(p)]+ans[rs(p)];
}
3.update更新函数
void upd(int nl,int nr,int l,int r,int p,int k)
{
if(nl<=l && r<=nr)
{
num[p]+=k;
ans[p]+=k*(r-l+1);
return;
}
int mid=(l+r)>>1;
num[ls(p)]+=num[p];
ans[ls(p)]+=num[p]*(mid-l+1);
num[rs(p)]+=num[p];
ans[rs(p)]+=num[p]*(r-mid);
num[p]=0;
if(nl<=mid) upd(nl,nr,l,mid,ls(p),k);
if(nr>mid) upd(nl,nr,mid+1,r,rs(p),k);
ans[p]=ansn[ls(p)]+ans[rs(p)];
}
4.get查询函数
int get(int x,int y,int l,int r,int p)
{
int anss=0;
if(x<=l && r<=y) return ans[p];
int mid=(l+r)>>1;
num[ls(p)]+=num[p];
ans[ls(p)]+=num[p]*(mid-l+1);
num[rs(p)]+=num[p];
ans[rs(p)]+=num[p]*(r-mid);
num[p]=0;
if(x<=l) anss+=get(x,y,l,mid,ls(p));
if(y>r) anss+=get(x,y,mid+1,r,rs(p));
return anss;
}
总代码:
#include<bits/stdc++.h>
using namespace std;
int a[400001],ans[400001],num[400001];
int ls(int x)
{
return x<<1;
}
int rs(int x)
{
return x<<1|1;
}
void build(int p,int l,int r)
{
if(l==r)
{
ans[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
ans[p]=ans[ls(p)]+ans[rs(p)];
}
void upd(int nl,int nr,int l,int r,int p,int k)
{
if(nl<=l && r<=nr)
{
num[p]+=k;
ans[p]+=k*(r-l+1);
return;
}
int mid=(l+r)>>1;
num[ls(p)]+=num[p];
ans[ls(p)]+=num[p]*(mid-l+1);
num[rs(p)]+=num[p];
ans[rs(p)]+=num[p]*(r-mid);
num[p]=0;
if(nl<=mid) upd(nl,nr,l,mid,ls(p),k);
if(nr>mid) upd(nl,nr,mid+1,r,rs(p),k);
ans[p]=ansn[ls(p)]+ans[rs(p)];
}
int get(int x,int y,int l,int r,int p)
{
int anss=0;
if(x<=l && r<=y) return ans[p];
int mid=(l+r)>>1;
num[ls(p)]+=num[p];
ans[ls(p)]+=num[p]*(mid-l+1);
num[rs(p)]+=num[p];
ans[rs(p)]+=num[p]*(r-mid);
num[p]=0;
if(x<=l) anss+=get(x,y,l,mid,ls(p));
if(y>r) anss+=get(x,y,mid+1,r,rs(p));
return anss;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n); //建树过程
cin>>m;
for(int i=1;i<=m;i++)
{
string s1;
cin>>s1;
if(s1=="ADD") {int j,d,s;cin>>j>>d>>s;update(j,d,1,n,1,s);} //更新树过程
if(s1=="QUERY") {int s,c;cin>>s>>c;cout<<get(s,c,1,n,1)<<endl;} //询问区间和
}
return 0;
}
--END--
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/p/15808709.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!