线段是是一个很好用的数据结构,特别是在于长长的板子
-----------------
链接:Miku
----------------
先来一份线段树1的代码
#include<iostream> #include<cstdio> #include<algorithm> int n,m; long long sum[400005], lazy[400005]; int f,x,y; long long k; void pushdown(int x, int L, int R){ if (lazy[x] != 0){ int mid = (L + R) >> 1; lazy[x << 1] += lazy[x]; lazy[x << 1 | 1] += lazy[x]; sum[x << 1] += lazy[x] * (mid - L + 1); sum[x << 1 | 1] += lazy[x] * (R - mid); lazy[x] = 0; } return; } void pushup(int x){ sum[x] = sum[x << 1] + sum[x << 1 | 1]; return; } void update(int x, int l, int r, int L, int R, long long d){ if (L <= l && r <= R){ lazy[x] += d; sum[x] += d * (r - l + 1); return; } int mid = (l + r) >> 1; pushdown(x, l, r); if (L <= mid) update(x << 1, l, mid, L, R, d); if (R > mid) update(x << 1 | 1, mid + 1, r, L, R, d); pushup(x); } long long query(int x, int l, int r, int L, int R){ if (L <= l && r <= R){ return sum[x]; } int mid = (l + r) >> 1; pushdown(x, l, r); long long ans = 0; if (L <= mid) ans += query(x << 1, l, mid, L, R); if (R > mid) ans += query(x << 1 | 1, mid + 1, r, L, R); return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ scanf("%d",&x); update(1, 1, n, i, i, x); } for(int i=1;i<=m;++i){ scanf("%d",&f); if(f==1){ scanf("%d%d%lld",&x,&y,&k); update(1, 1, n, x, y, k); } else{ scanf("%d%d",&x,&y); printf("%lld\n", query(1, 1, n, x, y)); } } return 0; }