///区间求和
const int maxn=100000;
int N,Q; // N为区间右端点(即数的个数),Q为查询次数
long long m;
struct xx{
long long sum,inf; //inf,延迟更新,当需要更新时才更新,否则存放入 inf
}tree[4*maxn+10]; //一般都开4倍
void build(int l,int r,int root){ //建树 调用为 build(1,N,1);
tree[root].inf=0;
if(l==r){
scanf("%lld",&m);
tree[root].sum=m;
} else {
int mid=(l+r)/2;
build(l,mid,root*2);
build(mid+1,r,root*2+1);
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}
}
void pushdown(int l,int r,int root){ //向下更新
int mid=(l+r)/2;
tree[root*2].inf+=tree[root].inf; //注意, 有的题中 是替换的意思, 则 直接 = 就行,不用 += (以下的 += 符号也一样)
tree[root*2+1].inf+=tree[root].inf;
tree[root*2].sum+=(mid-l+1)*tree[root].inf;
tree[root*2+1].sum+=(r-(mid+1)+1)*tree[root].inf;
tree[root].inf=0;
return ;
}
void update(int l,int r,int ul,int ur,int add,int root){ //更新区间, ul,ur为需要更新的区间
if(ul<=l&&r<=ur){
tree[root].sum+=(r-l+1)*add;
tree[root].inf+=add;
} else {
if(tree[root].inf!=0) pushdown(l,r,root);
int mid=(l+r)/2;
if(ul<=mid) update(l,mid,ul,ur,add,root*2);
if(ur>mid) update(mid+1,r,ul,ur,add,root*2+1);
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}
}
long long query(int l,int r,int ql,int qr,int root){ //查询, ql qr 为查询的区间
if(ql<=l&&r<=qr)
return tree[root].sum;
else {
if(tree[root].inf!=0) pushdown(l,r,root);
int mid=(l+r)/2;
long long ans=0;
if(ql<=mid) ans+=query(l,mid,ql,qr,root*2);
if(qr>mid) ans+=query(mid+1,r,ql,qr,root*2+1);
return ans;
}
}