线段树模板(待补完)

因为每次写线段树都要纠结好久...于是决定将成型的模板放在这里 以后直接打上去就好了=-=

建树:

tips1:初值都是0可以省略

tips2:对于不同的维护值要用不同的标记

 

void build(ll l,ll r,ll pos)
{
	if(l==r)
	{
		tr[pos].w=a[l];
		return ;
	}
	ll mid=l+r>>1;
	build(l,mid,pos<<1);
	build(mid+1,r,pos<<1|1);
	tr[pos].w=tr[pos<<1].w+tr[pos<<1|1].w;
}

 

 单点查询:

 

ll ask(ll l,ll r,ll pos,ll x)
{
	if(l==r)
	{
		return tr[pos].w;
	}
	if(tr[pos].f)down(pos);
	ll mid=l+r>>1;
	if(mid>=x)return ask(l,mid,pos<<1,x);
	else return ask(mid+1,r,pos<<1|1,x);
}

 

 区间加:

void add(ll l,ll r,ll pos,ll a,ll b,ll x)
{
	if(l>=a&&r<=b)
	{
		tr[pos].w+=x;
		tr[pos].f+=x;
		return ;
	}
	ll mid=l+r>>1;
	if(tr[pos].f)down(pos);
	if(b<=mid)
	add(l,mid,pos<<1,a,b,x);
	else if(a>mid)
	add(mid+1,r,pos<<1|1,a,b,x);
	else add(l,mid,pos<<1,a,b,x),add(mid+1,r,pos<<1|1,a,b,x);
	tr[pos].w=tr[pos<<1].w+tr[pos<<1|1].w;
}

 

打标记:

void down(ll pos)
{
	ll x=tr[pos].f;
	tr[pos<<1].f+=x;
	tr[pos<<1|1].f+=x;
	tr[pos].f=0;
}

 

posted @ 2017-09-27 10:02  a799091501  阅读(161)  评论(0编辑  收藏  举报