来自cyc的线段树1
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; long long n,m,k,x,y; long long a[100000]; struct tree { long long l,r,sum,tag; }t[400000]; long long ls(long long rt){return rt << 1;} long long rs(long long rt){return rt << 1 | 1;} void build(long long rt,long long l,long long r) { t[rt].l = l,t[rt].r = r; if(l == r) { t[rt].sum = a[l]; return; } long long mid = (l + r) >> 1; build(ls(rt),l,mid); build(rs(rt),mid+1,r); t[rt].sum = t[ls(rt)].sum + t[rs(rt)].sum; } void push_down(long long rt) { t[ls(rt)].sum += t[rt].tag * (t[ls(rt)].r - t[ls(rt)].l + 1); t[rs(rt)].sum += t[rt].tag * (t[rs(rt)].r - t[rs(rt)].l + 1); t[ls(rt)].tag += t[rt].tag; t[rs(rt)].tag += t[rt].tag; t[rt].tag = 0; } void change(long long rt,long long l,long long r,long long x) { if(l <= t[rt].l && r >= t[rt].r) { t[rt].sum += (t[rt].r - t[rt].l + 1) * x; t[rt].tag += x; return; } if(t[rt].tag) push_down(rt); if(l <= t[ls(rt)].r) { change(ls(rt),l,r,x); } if(r >= t[rs(rt)].l) { change(rs(rt),l,r,x); } t[rt].sum = t[ls(rt)].sum + t[rs(rt)].sum; } long long check(long long rt,long long l,long long r) { if(l <= t[rt].l && r >= t[rt].r) { return t[rt].sum; } if(t[rt].tag) push_down(rt); long long res = 0; if(l <= t[ls(rt)].r) { res += check(ls(rt),l,r); } if(r >= t[rs(rt)].l) { res += check(rs(rt),l,r); } return res; } int main() { cin >> n >> m; for(long long i = 1;i <= n; i++) cin >> a[i]; build(1,1,n); for(long long i = 1;i <= m; i++) { cin >> k; if(k == 1) { cin >> x >> y >> k; change(1,x,y,k); } else { cin >> x >> y; cout << check(1,x,y) << endl; } } return 0; }