数据类型为long long(long long的最大值:9223372036854775807)
#include <iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 1000001
using namespace std;
unsigned long long n;//总个数
unsigned long long tree [MAXN * 4];//线段树存储数组
unsigned long long tag [MAXN * 4];//lazy标签记录数组
unsigned long long a [MAXN];//存储读入数据
//根据序号x,寻找线段树的左右子树的序号
inline long long leftsearch(long long x) {
return x * 2;
}
inline long long rightsearch(long long x) {
return x * 2 + 1;
}
//构建线段树时,从最底层向上传递数据
inline void push_up(long long x) {
tree[x] = tree[leftsearch(x)] + tree[rightsearch(x)];
}
//创建线段树
void build(long long x, long long left, long long right) {
tag[x] = 0;
if (left == right) {//终止条件
tree[x] = a[left];
return;
}
long long mid = (left + right) / 2;
build(leftsearch(x), left, mid);//创建左子树
build(rightsearch(x), mid + 1, right);//创建右子树
push_up(x);//向上更新数据
}
//区间修改
inline void f(long long x, long long left, long long right, long long k) {//区间加法
tag[x] = tag[x] + k;
tree[x] = tree[x] + k * (right - left + 1);
}
inline void push_down(long long x, long long left, long long right) {
long long mid = (left + right) / 2;
f(leftsearch(x), left, mid, tag[x]);
f(rightsearch(x), mid + 1, right, tag[x]);
tag[x] = 0;
}
inline void update(long long nleft, long long nright, long long left, long long right, long long x, long long k) {//区间加法
if (nleft <= left && nright >= right) {
tree[x] += k * (right - left + 1);
tag[x] += k;
return ;
}
push_down(x, left, right);
long long mid = (left + right) / 2;
if (nleft <= mid)update(nleft, nright, left, mid, leftsearch(x), k);
if (nright > mid)update(nleft, nright, mid + 1, right, rightsearch(x), k);
push_up(x);
}
//区间查询
long long query(long long nleft, long long nright, long long left, long long right, long long x) {
long long res = 0;
if (nleft <= left && nright >= right)return tree[x];
long long mid = (left + right) / 2;
push_down(x, left, right);
if (nleft <= mid)res += query(nleft, nright, left, mid, leftsearch(x));
if (nright > mid)res += query(nleft, nright, mid + 1, right, rightsearch(x));
return res;
}
以上为线段树基本函数;
配合洛谷p3372题,写出主函数:
int main()
{
cin >> n >> m;
long long x,b,c,d,e,f;
for (long long i = 1; i <= n; i++) {
scanf_s("%lld", &a[i]);
}
build(1, 1, n);
for (long long i = 0; i < m; i++) {
int key;
scanf_s("%d", &key);
switch (key)
{
case 1: {
scanf_s("%lld%lld%lld", &b, &c, &d);
update(b, c, 1, n, 1, d);
break;
}
case 2: {
scanf_s("%lld%lld", &e, &f);
printf("%lld\n", query(e, f, 1, n, 1));
break;
}
}
}
return 0;
}