标签:整数 线段树 button efault gets open 操作 base ret
如题,已知一个数列,你需要进行下面两种操作:
第一行包含两个整数 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 的结果。
输入
5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4
输出
11
8
20
#include<iostream> #include<cstdio> using namespace std; long long a[100001], c[100001],sum[100001]; int n, m; long long lowbit(long long x) { return x&(-x); } void update(long long i, long long k) { long long x = i; while (i <= n) { c[i] += k; sum[i] += (x-1)*k; i += lowbit(i); } } long long getsum(long long i) { long long res = 0; long long x = i; while (i > 0) { res += c[i]*x-sum[i]; i -= lowbit(i); } return res; } int main() { long long type,x,y,k; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); update(i, a[i]-a[i-1]); } for (int i = 0; i < m; i++) { scanf("%lld %lld %lld", &type,&x,&y); if (type == 1) { scanf("%lld", &k); update(x, k); update(y + 1, -k); } else { printf("%lld\n", getsum(y) - getsum(x - 1)); } } }
开始int 溢出,改为long long通过
标签:整数 线段树 button efault gets open 操作 base ret
原文地址:https://www.cnblogs.com/Jason66661010/p/12820946.html