zoukankan      html  css  js  c++  java
  • AcWing1264. 动态求连续区间和 (线段树做法)

    1、题目

    给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和。

    输入格式
    第一行包含两个整数 n 和 m,分别表示数的个数和操作次数。

    第二行包含 n 个整数,表示完整数列。

    接下来 m 行,每行包含三个整数 k,a,b (k=0,表示求子数列[a,b]的和;k=1,表示第 a 个数加 b)。

    数列从 1 开始计数。

    输出格式
    输出若干行数字,表示 k=0 时,对应的子数列 [a,b] 的连续和。

    数据范围

    [1≤n≤100000, 1≤m≤100000, 1≤a≤b≤n ]

    输入样例:

    10 5
    1 2 3 4 5 6 7 8 9 10
    1 1 5
    0 1 3
    0 4 8
    1 7 5
    0 4 8
    

    输出样例:

    11
    30
    35
    

    2、题意分析

    1、知识点

    考察线段树和树状数组的知识、线段树的关键在于建树和递归求和的过程。


    3、代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 100010;
    
    int n, m;
    int w[N];
    
    struct Node
    {
        int l, r;
        int sum;
    }tr[4 * N];
    
    void pushup(int u)  // 更新和
    {
        tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
    }
    
    void build(int u, int l, int r) // 建立线段树
    {
        if(l == r) tr[u] = {l, r, w[r]};
        else
        {
            tr[u] = {l, r};
            int mid = l + r >> 1;
            build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
            pushup(u);
        }
    }
    
    int query(int u, int l, int r)  // 查询[l, r]的值
    {
        if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
        int mid = tr[u].l + tr[u].r >> 1;
        int sum = 0;
        if(l <= mid) sum = query(u << 1, l, r);
        if(r > mid) sum += query(u << 1 | 1, l, r);
        return sum;
    }
    
    void modify(int u, int x, int v)    // 将x的值修改为v
    {
        if(tr[u].l == tr[u].r) tr[u].sum += v;
        else
        {
            int mid = tr[u].l + tr[u].r >> 1;
            if(x <= mid) modify(u << 1, x, v);
            else modify(u << 1 | 1, x, v);
            pushup(u);
        }
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n ; i ++) scanf("%d", &w[i]);
        build(1, 1, n); //建树
        
        int k, a, b;
        while(m --)
        {
            scanf("%d%d%d", &k, &a, &b);
            if(k == 0) printf("%d
    ", query(1, a, b));
            else modify(1, a, b);
        }
        return 0;
    }
    
  • 相关阅读:
    jquery.js 一个非常不错的本脚库。
    AjaxPro 框架学习 (支持vs2003/vs2005)
    利用HttpResponse来导出excel文件.
    一个比较好的WEB时间控件
    CCR 编写一个不用创建线程,不用考虑资源互斥的多线程程序
    页面优化 .net 版
    [转]window.opener用法
    导出excel文件 解决科学计数法问题
    抽象类和抽象方法的特征和用途
    超强悍的右键菜单
  • 原文地址:https://www.cnblogs.com/xiaofrank/p/14462268.html
Copyright © 2011-2022 走看看