#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 10;
ll arr[MAXN] = {0};
ll tree[MAXN * 4 + 10] = {0};
ll b[MAXN] = {0};
void init(int now, int l, int r)
{
if(l == r)
{
tree[now] = arr[l];
return ;
}
int mid = l + (r - l) / 2;
init(now * 2, l, mid);
init(now * 2 + 1, mid + 1, r);
tree[now] = tree[now * 2] + tree[now * 2 + 1];
}
void pushdown(int now, int l , int r)
{
if(b[now])
{
b[now * 2] += b[now];
b[now * 2 + 1] += b[now];
int mid = l + (r - l) / 2;
tree[now * 2] += b[now] * (mid - l + 1);
tree[now * 2 + 1] += b[now] * (r - mid);
b[now] = 0;
}
}
ll find(int now, int l, int r, int x, int y)
{
if(x > r || y < l)
return 0;
if(x <= l && y >= r)
{
return tree[now];
}
pushdown(now, l, r);
int mid = l + (r - l) / 2;
ll ans = 0;
ans += find(now * 2, l, mid, x, y);
ans += find(now * 2 + 1, mid + 1, r, x, y);
return ans;
}
void update(int now, int l, int r, int x, int y, ll add)
{
if(l > y || x > r)
return ;
if(l >= x && r <= y)
{
b[now] += add;
tree[now] += add * (r - l + 1);
return ;
}
pushdown(now, l, r);
int mid = l + (r - l) / 2;
update(now * 2, l, mid, x, y, add);
update(now * 2 + 1, mid + 1, r, x , y, add);
tree[now] = tree[now * 2] + tree[now * 2 + 1];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll len, oprt;
cin>>len>>oprt;
for(int i = 1; i <= len; i++)
cin>>arr[i];
init(1, 1, len);
int x, y;
while(oprt--)
{
int mode, x, y, k;
cin>>mode;
if(mode == 1)
{
cin>>x>>y>>k;
update(1, 1, len, x, y, k);
}
else
{
cin>>x>>y;
cout<<find(1, 1, len, x, y)<<endl;
}
}
return 0;
}
[线段树] [模板]
猜你喜欢
转载自blog.csdn.net/Zeolim/article/details/81585577
今日推荐
周排行