zoukankan      html  css  js  c++  java
  • poj3468 线段树

      http://poj.org/problem?id=3468 题目链接, 很经典的线段树的应用, 这里复习一下, 再写一遍, 代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int maxn = 100000 + 10;
    int N, Q;
    int a[maxn];
    struct Segment{
        int l, r;
        long long sum;
        int lazy;
    }seg[3*maxn];
    
    void build(int rt, int l, int r){
        seg[rt].l = l; seg[rt].r = r;
        seg[rt].lazy = 0;
        if(l==r){
            seg[rt].sum = a[l];
            return ;
        }
        int chl = 2*rt, chr = 2*rt+1;
        int mid = (l+r)/2;
        build(chl, l, mid);
        build(chr, mid+1, r);
        seg[rt].sum = seg[chl].sum + seg[chr].sum;
    }
    
    void push_down(int rt){
        int chl = 2*rt, chr = 2*rt+1;
        if(seg[rt].lazy){
            seg[chl].sum += (long long)seg[rt].lazy*(long long)(seg[chl].r-seg[chl].l+1);
            seg[chl].lazy += seg[rt].lazy;
            seg[chr].sum += (long long)seg[rt].lazy*(long long)(seg[chr].r-seg[chr].l+1);
            seg[chr].lazy += seg[rt].lazy;
            seg[rt].lazy = 0;
        }
    }
    
    void update(int rt, int l, int r, int c){
        if(seg[rt].l==l && seg[rt].r==r){
            seg[rt].sum += (long long)c*(r-l+1);
            seg[rt].lazy += c;
            return ;
        }
        push_down(rt);
        int mid = (seg[rt].l+seg[rt].r)/2;
        if(r <= mid)
            update(2*rt, l, r, c);
        else if(l>mid)
            update(2*rt+1, l, r, c);
        else{
            update(2*rt, l, mid, c);
            update(2*rt+1, mid+1, r, c);
        }
        seg[rt].sum = seg[2*rt].sum + seg[2*rt+1].sum;
    }
    
    long long query(int rt, int l, int r){
        if(seg[rt].l==l && seg[rt].r==r){
            return seg[rt].sum;
        }
        push_down(rt);
        int mid = (seg[rt].l+seg[rt].r)/2;
        if(r <= mid)
            return query(2*rt, l, r);
        else if(l > mid)
            return query(2*rt+1, l, r);
        else {
            long long v1 = query(2*rt, l, mid);
            long long v2 = query(2*rt+1, mid+1, r);
            return v1 + v2;
        }
        seg[rt].sum = seg[2*rt].sum + seg[2*rt+1].sum;
    }
    int main() {
        scanf("%d%d", &N, &Q);
        for(int i=1; i<=N; i++)
            scanf("%d", &a[i]);
        build(1, 1, N);
        for(int i=0; i<Q; i++){
            char s[6];
            scanf("%s", s);
            if(s[0] == 'Q'){
                int l, r;
                scanf("%d%d", &l, &r);
                printf("%lld
    ", query(1, l, r));
            }else{
                int l, r, c;
                scanf("%d%d%d", &l, &r, &c);
                update(1, l, r, c);
            }
        }
        return 0;
    }
  • 相关阅读:
    uni-app实现下拉效果
    求点到已知直线的距离和点到直线的垂点坐标
    Mybatis 自定义SqlSessionFactoryBean扫描通配符typeAliasesPackage
    前端string类型的日期 -后端实体类属性为Date
    如何更新npm为最新版本
    简述ThreadPoolExecutor的运行机制
    list在遍历过程中的add/remove
    Linux下安装mysql
    Linux下安装activeMQ并设置开机启动
    solr集群环境搭建
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5396966.html
Copyright © 2011-2022 走看看