码迷,mamicode.com
首页 > 其他好文 > 详细

线段树

时间:2017-07-06 13:14:03      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:ring   iostream   stream   class   cpp   tmp   div   root   dev   

(CodeVS:1082)

C++指针版

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
struct rec{
	ll l,r,delta,sum;
	rec *lc,*rc;
};
rec *root;
ll l,r,add,n,m,tmp;
void update(rec *now,ll l,ll r,ll add)
{
	if ((l<=now->l)&&(now->r<=r))
	{
		now->delta+=add;
		return;
	}
	if (l<=(now->l+now->r)/2) update(now->lc,l,r,add);
	if (r>(now->l+now->r)/2) update(now->rc,l,r,add);
	now->sum=now->lc->sum+(now->lc->r-now->lc->l+1)*now->lc->delta;
	now->sum+=now->rc->sum+(now->rc->r-now->rc->l+1)*now->rc->delta;
}
void build(rec *now,ll l,ll r)
{
	now->l=l;now->r=r;
	if (l==r)
	{
		scanf("%lld",&now->sum);
		now->lc=NULL;now->rc=NULL;
		return;
	}
	now->lc=new rec;
	now->rc=new rec;
	build(now->lc,l,(l+r)/2);
	build(now->rc,(l+r)/2+1,r);
	now->sum=now->lc->sum+now->rc->sum;
}
ll query(rec *now,ll l,ll r)
{
	ll ret=0;
	if ((l<=now->l)&&(now->r<=r))return now->sum+now->delta*(now->r-now->l+1);
	now->lc->delta+=now->delta;
	now->rc->delta+=now->delta;
	now->sum+=now->delta*(now->r-now->l+1);
	now->delta=0;
	if (l<=(now->l+now->r)/2)ret=query(now->lc,l,r);
	if (r>(now->r+now->l)/2)ret+=query(now->rc,l,r);
	return ret;
}
int main()
{
	root=new rec;
	scanf("%lld",&n);
	build(root,1,n);
	scanf("%lld",&m);
	for (int i=1;i<=m;i++)
	{
		scanf("%lld",&tmp);
		if (tmp==1)
		{
			scanf("%lld %lld %lld",&l,&r,&add);
			update(root,l,r,add);			
		}
		if (tmp==2)
		{
			scanf("%lld %lld",&l,&r);
			printf("%lld\n",query(root,l,r));
		}
	}
}

  

线段树

标签:ring   iostream   stream   class   cpp   tmp   div   root   dev   

原文地址:http://www.cnblogs.com/mczhuang/p/7125625.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!