KIDx的解题报告
?
题目链接:http://lightoj.com/volume_showproblem.php?problem=1164
?
题意:区间内初始时全部为0
命令1:0 x y v; 从x到y全部+v
命令2:1 x y; 输出x到y的值的总和
典型lazy的应用
#include <iostream> #include <fstream> #include <algorithm> #include <string> #include <set> #include <map> #include <queue> #include <utility> #include <iomanip> #include <stack> #include <list> #include <vector> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <ctype.h> using namespace std; #define inf 0x3fffffff #define M 100005 #define LL long long #define Max 26 struct Node{ int l, r; //sum是l到r的总和 LL v, sum; //v积累要加的数,需要往下时才更新儿子:lazy标记 }N[M<<2]; void create (int u, int a, int b) { N[u].l = a, N[u].r = b, N[u].v = N[u].sum = 0; if (a == b) return ; int mid = (a + b) >> 1, lc = u+u, rc = lc+1; create (lc, a, mid); create (rc, mid+1, b); } void update (int u, int a, int b, LL c) { if (a <= N[u].l && b >= N[u].r) { N[u].v += c; N[u].sum += c * (N[u].r-N[u].l+1); //注意积累是用+= return ; } int lc = u+u, rc = lc+1; if (N[u].v > 0) //lazy一下,需要访问我儿子,我才去更新 { N[lc].v += N[u].v; N[lc].sum += N[u].v * (N[lc].r-N[lc].l+1); N[rc].v += N[u].v; N[rc].sum += N[u].v * (N[rc].r-N[rc].l+1); N[u].v = 0; } if (a <= N[lc].r) update (lc, a, b, c); if (b >= N[rc].l) update (rc, a, b, c); N[u].sum = N[lc].sum + N[rc].sum; } LL find (int u, int a, int b)?//和比较大,要用long long { if (a <= N[u].l && b >= N[u].r) return N[u].sum; LL m1 = 0, m2 = 0; int lc = u+u, rc = lc+1; if (N[u].v > 0) //同理lazy一下 { N[lc].v += N[u].v; N[lc].sum += N[u].v * (N[lc].r-N[lc].l+1); N[rc].v += N[u].v; N[rc].sum += N[u].v * (N[rc].r-N[rc].l+1); N[u].v = 0; } if (a <= N[lc].r) m1 = find (lc, a, b); if (b >= N[rc].l) m2 = find (rc, a, b); return m1+m2; } int main() { LL c; int t, cc = 1, n, q, k, a, b; scanf ("%d", &t); while (t--) { scanf ("%d%d", &n, &q); create (1, 1, n); printf ("Case %d:\n", cc++); while (q--) { scanf ("%d%d%d", &k, &a, &b); a++, b++; if (k) printf ("%lld\n", find (1, a, b)); else scanf ("%lld", &c), update (1, a, b, c); } } return 0; }
?