题目描述
如题,已知一个数列,你需要进行下面两种操作:
- 将某区间每一个数加上 kk。
- 求出某区间每一个数的和。
输入格式
第一行包含两个整数 n, mn,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 nn 个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。
接下来 mm 行每行包含 33 或 44 个整数,表示一个操作,具体如下:
1 x y k
:将区间 [x, y][x,y] 内每个数加上 kk。2 x y
:输出区间 [x, y][x,y] 内每个数的和。
输出格式
输出包含若干行整数,即为所有操作 2 的结果。
输入输出样例
输入 #1复制
5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4
输出 #1复制
11 8 20
说明/提示
对于 30\%30% 的数据:n \le 8n≤8,m \le 10m≤10。
对于 70\%70% 的数据:n \le {10}^3n≤103,m \le {10}^4m≤104。
对于 100\%100% 的数据:1 \le n, m \le {10}^51≤n,m≤105。
保证任意时刻数列中任意元素的和在 [-2^{63}, 2^{63})[−263,263) 内。
【样例解释】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6+10;
ll in[MAXN];
struct info{
int l,r;
ll lz,sum;
}node[MAXN];
void build(int n,int l,int r)
{
node[n].l = l;node[n].r = r;
if(l == r){
node[n].sum = in[l];
return;
}
ll mid = (l+r) >> 1;
int next = n << 1;
build(next,l,mid);
build(next+1,mid+1,r);
node[n].sum = node[next].sum + node[next+1].sum;
}
void push_down(int n)
{
int next = n << 1;
if(node[n].lz){
node[next].lz += node[n].lz;
node[next+1].lz += node[n].lz;
ll mid = (node[n].l+node[n].r) >> 1;
node[next].sum += node[n].lz * (mid - node[n].l+1);
node[next+1].sum += node[n].lz * (node[n].r - mid);
node[n].lz = 0;
}
return;
}
void add(int n,int l,int r,int k)
{
if(node[n].l >= l && node[n].r <= r){
node[n].sum += 1ll*k*(node[n].r - node[n].l + 1);
node[n].lz += k;
return;
}
push_down(n);
int next = n << 1;
if(node[next].r >= l)
add(next,l,r,k);
if(node[next+1].l <= r)
add(next+1,l,r,k);
node[n].sum = node[next].sum + node[next+1].sum;
}
ll search(int n,int l,int r)
{
if(node[n].l >= l && node[n].r <= r) return node[n].sum;
if(node[n].r < l || node[n].l > r) return 0;
push_down(n);
int next = n << 1;
ll s = 0;
if(node[next].r >= l)
s += search(next,l,r);
if(node[next+1].l <= r)
s += search(next+1,l,r);
return s;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i = 1;i <= n; i++)
scanf("%d",&in[i]);
build(1,1,n);
int t,x,y,k;
for(int i = 0;i < m; i++){
scanf("%d",&t);
if(t == 1){
scanf("%d %d %d",&x,&y,&k);
add(1,x,y,k);
}
else{
scanf("%d %d",&x,&y);
ll res = search(1,x,y);
printf("%lld\n",res);
}
}
return 0;
}