【codevs 1082】线段树练习3

来源:互联网 发布:nextcloud config.php 编辑:程序博客网 时间:2024/05/16 16:06
#include <cstdio>#include <iostream>#include <cstring>#define ll long longusing 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;}

0 0