您的位置:首页 > 其它

【codevs 1082】线段树练习3

2016-04-04 08:33 218 查看
#include <cstdio>
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
int a[200000],n,Q;
struct edge{
int l,r,add;ll sum;
}node[200000*4];
void pushdown(int k)
{
node[k<<1].add += node[k].add;
node[k<<1].sum += (node[k<<1].r-node[k<<1].l+1)*node[k].add;
node[(k<<1)+1].add += node[k].add;
node[(k<<1)+1].sum += (node[(k<<1)+1].r-node[(k<<1)+1].l+1)*node[k].add;
node[k].add = 0;
}

void update(int k,int left,int right,int x)
{
if(left <= node[k].l && right >= node[k].r)
{
node[k].add += x;
node[k].sum += (node[k].r-node[k].l+1)*x;
return;
}
node[k].sum += (right-left+1)*x;
if(node[k].add)pushdown(k);
int mid = (node[k].l+node[k].r)>>1;
if(right <= mid)update(k<<1,left,right,x);
else if(left > mid)update((k<<1)+1,left,right,x);
else
{
update(k<<1,left,mid,x);
update((k<<1)+1,mid+1,right,x);
}
}

ll query(int k,int left,int right)
{
if(left <= node[k].l && right >= node[k].r)return node[k].sum;
if(node[k].add)pushdown(k);
int mid = (node[k].l+node[k].r)>>1;
if(right <= mid)return query(k<<1,left,right);
else if(left > mid)return query((k<<1)+1,left,right);
else return (query(k<<1,left,mid)+query((k<<1)+1,mid+1,right));
}

void build(int k,int left,int right)
{
node[k].l = left,node[k].r = right;
node[k].add = 0;
if(node[k].l == node[k].r)
{
node[k].sum = a[left];
return;
}
int mid = (left+right)>>1;
build(k<<1,left,mid);
build((k<<1)+1,mid+1,right);
node[k].sum = node[k<<1].sum + node[(k<<1)+1].sum;
}

int main()
{
cin>>n;
for(int i = 1;i <= n;i++)scanf("%d",&a[i]);
build(1,1,n);
cin>>Q;
for(int i = 1;i <= Q;i++)
{
int s,a,b,x;scanf("%d",&s);
if(s == 1)
{
scanf("%d%d%d",&a,&b,&x);
update(1,a,b,x);
}
else
{
scanf("%d%d",&a,&b);
cout<<query(1,a,b)<<"\n";
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: