• POJ 3468_A Simple Problem with Integers(线段树)


    题意:

    给定序列及操作,求区间和。

    分析:

    线段树,每个节点维护两个数据:

    • 该区间每个元素所加的值
    • 该区间元素和

    可以分为“路过”该区间和“完全覆盖”该区间考虑。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    //[l,r)
    const int maxn = 300005;
    ll sum[maxn], add[maxn];
    int v[maxn];
    void update(int a, int b, int x, int k, int l, int r)
    {
        if(a <= l && r <= b) add[k] += x;
        else if(l < b && a < r){
            sum[k] += (min(r,b) - max(l,a))*x;
            update(a, b, x, k * 2 + 1, l, (l+r)/2);
            update(a, b,x, k * 2 + 2, (l+r)/2, r);
        }
    }
    ll query(int a, int b, int k, int l, int r)
    {
        if(a >= r|| b <= l) return 0;
        else if(a <= l&&r <= b) return (r - l) * add[k] + sum[k];
        else {
            ll res = (min(b,r)-max(a,l)) * add[k];
            res += query(a, b, k * 2 + 1, l, (l+r)/2);
            res += query(a, b, k * 2 + 2, (l + r)/2, r);
            return res;
        }
    }
    int main (void)
    {
        int n, q;scanf("%d%d",&n,&q);
        int a, b, c;
        for(int i = 0; i < n; i++){
            scanf("%d",&v[i]);
            update(i, i + 1, v[i], 0, 0, n);
        }
        for(int i = 0; i < q; i++){
            getchar();
            if(getchar()=='C'){
                scanf("%d%d%d", &a, &b, &c);
                update(a-1, b, c, 0 , 0, n);
            }else{
                scanf("%d%d",&a, &b);
                printf("%I64d
    ",query(a - 1, b, 0, 0, n));
            }
        }
        return 0;
    }
    

    写的时候还是磕磕绊绊,看来当初学的时候理解的并不好

  • 相关阅读:
    Json模块的详细介绍(序列化)
    Selenium 报错:Element is not clickable at point
    对于页面弹出框的处理
    RF操作滚动条(竖拉)
    xpath定位中starts-with、contains和text()的用法
    Python 之ConfigParser模块
    解读Loadrunner网页细分图(Web Page Diagnostics)
    ant 入门级详解
    Postman接口测试_添加断言
    算法:顺时针打印数组
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758797.html
Copyright © 2020-2023  润新知