题意:假设货架上从左到右摆放了N种商品,并且依次标号为1到N,其中标号为i的商品的价格为Pi。小Hi的每次操作分为两种可能,第一种是修改价格——小Hi给出一段区间[L, R]和一个新的价格NewP,所有标号在这段区间中的商品的价格都变成NewP。第二种操作是询问——小Hi给出一段区间[L, R],而小Ho要做的便是计算出所有标号在这段区间中的商品的总价格,然后告诉小Hi。
需要用到推迟对子节点的更新。直接更新孩子节点没有必要,这样会增加时间复制的。当访问到的时候再去更新孩子节点。
还是使用数组来存储完全二叉树的结构,初始化时,lazy都为false。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define M 100005 int arr[M]; struct Node{ int l, r, sum; bool lazy; }; Node nodes[4 * M]; void buildTree(int l, int r, int i){ nodes[i].l = l; nodes[i].r = r; nodes[i].lazy = false; if (l == r){ nodes[i].sum = arr[l]; return; } int mid = (l + r) >> 1; buildTree(l, mid, i * 2); buildTree(mid + 1, r, i * 2 + 1); nodes[i].sum = nodes[i * 2].sum + nodes[i * 2 + 1].sum; //!!! } void update(int l, int r, int v, int i){ if (nodes[i].lazy) pushdown(i); if (nodes[i].l == l && nodes[i].r == r){ nodes[i].sum = (nodes[i].r - nodes[i].l + 1)*v; nodes[i].lazy = true; return; } int mid = (nodes[i].l + nodes[i].r) >> 1; if (r <= mid) update(l, r, v, i * 2); else if (l > mid) update(l, r, v, i * 2 + 1); else{ update(l, mid, v, i * 2); update(mid + 1, r, v, i * 2 + 1); } nodes[i].sum = nodes[i * 2].sum + nodes[i * 2 + 1].sum; //!!! } void pushdown(int i){ if (nodes[i].lazy){ nodes[i * 2].lazy = true; nodes[i * 2 + 1].lazy = true; nodes[i].lazy = false; int avg = nodes[i].sum / (nodes[i].r - nodes[i].l + 1); nodes[i * 2].sum = avg * (nodes[i * 2].r - nodes[i].l + 1); nodes[i * 2 + 1].sum = avg * (nodes[i * 2 + 1].r - nodes[i * 2 + 1].l + 1); } } int query(int l, int r, int i){ if (nodes[i].lazy) pushdown(i); if (nodes[i].l == l && nodes[i].r == r){ return nodes[i].sum; } int mid = (nodes[i].l + nodes[i].r) >> 1; if (r <= mid){ return query(l, r, i * 2); } else if (l > mid){ return query(l, r, i * 2 + 1); } else{ return query(l, mid, 2 * i) + query(mid + 1, r, 2 * i + 1); } } int main(){ int i, m, n, f, l, r, price; while (scanf("%d", &n) != EOF){ for (i = 1; i <= n; ++i){ scanf("%d", &arr[i]); } buildTree(1, n, 1); scanf("%d", &m); while (m--){ scanf("%d", &f); if (f == 1){ scanf("%d%d%d", &l, &r, &price); update(l, r, price, 1); } else{ scanf("%d%d", &l, &r); printf("%d ", query(l, r, 1)); } } } return 0; }