线段树区间更新

区间更新:运用延迟标记(或则说是懒惰标记),简单说就是每次更新的时候不要更新到底,运用延迟标记使得更新延迟到下次需要更新或者询问的时候。

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;
}
View Code

 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;
}
View Code
原文地址:https://www.cnblogs.com/solvit/p/9561931.html