zoukankan      html  css  js  c++  java
  • 线段树模板1

    已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.求出某区间每一个数的和

    即支持区间修改(区间加)和区间查询。

    (这里的修改顺序对结果无影响)

    代码如下:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int maxn=200010;
    int m, n, f, a[maxn];
    long long sumv[maxn<<2], addv[maxn<<2];
    
    void build_tree(int o, int L, int R) {
        if (L==R) addv[o]=sumv[o]=a[L];
        else {
            int M=L+((R-L)>>1);
            int lc=(o<<1), rc=((o<<1)+1);
            build_tree(lc, L, M);
            build_tree(rc, M+1, R);
            sumv[o]=sumv[lc]+sumv[rc];
        }
        return;
    }
    
    int yl, yr;
    long long query(int o, int L, int R, long long add) {
        if (yl<=L && R<=yr) return sumv[o]+add*(R-L+1);
        int M=L+((R-L)>>1);
        long long sum=0;
        int lc=(o<<1), rc=((o<<1)+1);
        if (yl<=M) sum+=query(lc, L, M, add+addv[o]);
        if (yr>M) sum+=query(rc, M+1, R, add+addv[o]);
        return sum;
    }
    
    void maintain(int o, int L, int R) {
        int lc=(o<<1), rc=((o<<1)+1);
        sumv[o]=addv[o]*(R-L+1);
        if (R>L) sumv[o]+=sumv[lc]+sumv[rc];
        return;
    }
    
    int ql, qr;
    int v;
    void update(int o, int L, int R) {
        if (ql<=L && R<=qr) addv[o]+=v;
            else {
                int M=L+((R-L)>>1);
                int lc=(o<<1), rc=((o<<1)+1);
                if (ql<=M) update(lc, L, M);
                if (qr>M) update(rc, M+1, R);
          }
          maintain(o, L, R);
        return;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i=1; i<=n; i++) scanf("%d", &a[i]);
        build_tree(1, 1, n);
        while (m--){
            scanf("%d", &f);
            if (f==1) {
                scanf("%d%d%d", &ql, &qr, &v);
                update(1, 1, n);
            } else {
                scanf("%d%d", &yl, &yr);
                printf("%lld
    ",query(1, 1, n, 0));
            }
        }
        return 0;
    }

     题目见洛谷P3372

    (貌似也可以用分块和树状数组水过的样子,虽然我暂时并不知道树状数组是怎么做到的(嗯,以后一定会学的))

    因为数据范围long long的问题一直70分....

  • 相关阅读:
    Android绝黑剑之AutoCompleteTextView、MultiAutoCompleteTextView之智能联想
    F5 BIGIP负载均衡器配置实例与Web管理界面体验
    Java进阶之动态绑定
    某大型银行深化系统之二十:异常规范
    数据结构之排序
    数据结构之数组
    使用ssh来登录其它linux机器
    beanstalkc简易指令说明集
    ruby数组方法concat和push的区别
    uWSGI基础攻略
  • 原文地址:https://www.cnblogs.com/zjzj/p/7043900.html
Copyright © 2011-2022 走看看