加载中…

返回上一页

线段树板子

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;
}
posted @ 2022-01-16 07:44  1Liu  阅读(39)  评论(0编辑  收藏  举报