区间更新:运用延迟标记(或则说是懒惰标记),简单说就是每次更新的时候不要更新到底,运用延迟标记使得更新延迟到下次需要更新或者询问的时候。
HDU1698 Just a Hook
线段树功能:update成段区间更新,由于query只查询总区间,所以直接输出1结点(根节点)。
#include<bits/stdc++.h> using namespace std; #define lson l, mid, root << 1 #define rson mid + 1, r, root << 1 | 1 const int maxn = 100005; int col[maxn << 2],sum[maxn << 2]; int t,n,m; void PushUp(int root){ sum[root] = sum[root << 1] + sum[root << 1 | 1]; } void PushDown(int root,int x){ if(col[root]) { col[root << 1] = col[root << 1 | 1] = col[root]; sum[root << 1] = (x - (x >> 1)) * col[root]; sum[root << 1 | 1] = (x >> 1) * col[root]; col[root] = 0; } } void build(int l,int r,int root) { col[root] = 0; sum[root] = 1; if(l == r) return; int mid = (l + r) >> 1; build(lson);build(rson); PushUp(root); } void update(int L,int R,int c,int l,int r,int root) { if(L <= l && r <= R){ col[root] = c; sum[root] = c * (r - l + 1); return; } PushDown(root,r-l+1); int mid = (l + r) >> 1; if(L <= mid) update(L,R,c,lson); if(R > mid) update(L,R,c,rson); PushUp(root); } int main() { scanf("%d",&t); for(int cas = 1; cas <= t; cas++) { scanf("%d%d",&n,&m); build(1,n,1); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } printf("Case %d: The total value of the hook is %d. ",cas , sum[1]); } return 0; }
POJ3468 A Simple Problem with Integers
线段树功能:update区间加减更新,query区间求和。
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define lson l, mid, root << 1 #define rson mid + 1, r, root << 1 | 1 typedef long long ll; const int maxn = 100005; ll add[maxn],sum[maxn]; void PushUp(int root){ sum[root] = sum[root << 1] + sum[root << 1 | 1]; } void PushDown(int root,int c){ if(add[root]) { add[root << 1] += add[root]; add[root << 1 | 1] += add[root]; sum[root << 1] += add[root] * (c - (c >> 1)); sum[root << 1 | 1] += add[root] * (c >> 1); add[root] = 0; } } void build(int l,int r,int root) { add[root] = 0; if(l == r){ scanf("%lld",&sum[root]); return; } int mid = (l + r) >> 1; build(lson);build(rson); PushUp(root); } void update(int L,int R,int c,int l,int r,int root) { if(L <= l && r <= R){ add[root] += c; sum[root] += (ll)c * (r - l + 1); return; } PushDown(root,r - l + 1); int mid = (l + r) >> 1; if(L <= mid) update(L,R,c,lson); if(R > mid) update(L,R,c,rson); PushUp(root); } ll query(int L,int R,int l,int r,int root) { if(L <= l && r <= R){ return sum[root]; } PushDown(root,r - l + 1); int mid = (l + r) >> 1; ll ret = 0; if(L <= mid) ret += query(L,R,lson); if(R > mid) ret += query(L,R,rson); return ret; } int main() { int n,q; scanf("%d%d",&n,&q); build(1,n,1); while(q--) { char op[5]; int a,b,c; scanf("%s",op); if(op[0] == 'Q'){ scanf("%d%d",&a,&b); printf("%lld ",query(a,b,1,n,1)); } else{ scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } } return 0; }