hihoCoder week20 线段树的区间修改

区间修改 区间查询

最后一场比赛前的无可救药的热身

#include <bits/stdc++.h>
using namespace std;
#define mid ((l+r)/2)
#define ls (rt<<1)
#define rs (rt<<1|1)
const int N = 2e5+10;

int n, s[N], tr[N], lz[N];

void build(int rt,int l,int r)
{
    if(l ==r) {
        tr[rt] = s[l];
        return ;
    }
    build(ls,l,mid);
    build(rs,mid+1,r);
    tr[rt] = tr[ls] + tr[rs];
}

void down(int rt,int l,int r)
{
    if(lz[rt]) {
        lz[ls] = lz[rs] = lz[rt];
        tr[ls] = (mid-l+1) * lz[ls];
        tr[rs] = (r - mid) * lz[rs];
        lz[rt] = 0;
    }
} 

void update(int rt,int l,int r,int L,int R,int val)
{
    if(L <= l && r <= R) {
        lz[rt] = val;
        tr[rt] = val * (r-l+1);
        return ;
    }
    down(rt,l,r);
    if(L<=mid)
        update(ls,l,mid,L,R,val);
    if(R>mid)
        update(rs,mid+1,r,L,R,val);
    tr[rt] = tr[ls] + tr[rs];    
}

long long query(int rt,int l,int r,int L,int R)
{
    if(L <= l && r <= R) {
        return tr[rt];
    }
    down(rt,l,r);
    long long res = 0;
    if(L<=mid)
        res = res + query(ls,l,mid,L,R);
    if(R>mid)
        res = res + query(rs,mid+1,r,L,R);
    return res;
}
void out(int rt,int l,int r)
{
    printf("%d %d %d\n", l, r, tr[rt]);
    if(l == r) 
    return ;
    out(ls,l,mid);
    out(rs,mid+1,r);
}
int main()
{
    freopen("in.txt", "r", stdin);
    scanf("%d", &n);
    for(int i=1; i<=n; i++)
        scanf("%d", &s[i]);
    build(1,1,n);
    int m; scanf("%d", &m);
    while(m--) {
        int op,l,r;
        scanf("%d %d %d", &op, &l, &r);
        if(op) {
            int val; scanf("%d", &val);
            update(1,1,n,l,r,val);
            // out(1,1,n);
            //puts("-----");
        }else 
            printf("%lld\n", query(1,1,n,l,r));
    }
    return 0;
} 

 

posted @ 2018-11-24 19:58  Draymonder  阅读(133)  评论(0编辑  收藏  举报