zoukankan      html  css  js  c++  java
  • 单点更新,区间求和

    问题 M: 区间和

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 11  解决: 5
    [提交] [状态] [讨论版] [命题人:admin]

    题目描述

    给定一数列,规定有两种操作,一是修改某个元素,二是求区间的连续和。

    输入

    输入数据第一行包含两个正整数n,m(n<=100000,m<=500000),以下是m行,
    每行有三个正整数k,a,b(k=0或1, a,b<=n).k=0时表示将a处数字加上b,k=1时表示询问区间[a,b]内所有数的和。

    输出

    对于每个询问输出对应的答案。

    样例输入

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

    样例输出

    10
    6
    0
    6
    16
    6
    24
    14
    50
    41

    线段树和树状数组两种做法

    线段树代码:
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=4e5+10;
    typedef long long ll;
    struct node{
        int l,r,lazy;
        ll val;
    }tr[maxn];
     
    void Pushup(int i){
        tr[i].val=tr[i<<1].val+tr[i<<1|1].val;
    }
    void Pushdown(int i){
        if (tr[i].lazy){
            tr[i<<1].lazy+=tr[i].lazy;
            tr[i<<1|1].lazy+=tr[i].lazy;
            tr[i<<1].val+=1ll*(tr[i<<1].r-tr[i<<1].l+1)*tr[i].lazy;
            tr[i<<1|1].val+=1ll*(tr[i<<1|1].r-tr[i<<1|1].l+1)*tr[i].lazy;
            tr[i].lazy=0;
        }
    }
    void build(int l,int r,int i){
        tr[i].l=l,tr[i].r=r,tr[i].lazy=0;
        if(l==r) {
            tr[i].val=0;
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,i<<1);
        build(mid+1,r,i<<1|1);
        Pushup(i);
    }
    ll Query(int l,int r,int i){
        if(l<=tr[i].l && tr[i].r <=r) {
            return tr[i].val;
        }
        Pushdown(i);
        ll res=0;
        int mid=(tr[i].l+tr[i].r)>>1;
        if(l<=mid ) res+=Query(l,r,i<<1);
        if(r>mid) res+=Query(l,r,i<<1|1);
        return res;
    }
    void Update(int pos,int val,int i){
        if(tr[i].l==pos && tr[i].r ==pos){
            tr[i].val+=1ll*(tr[i].r-tr[i].l+1)*val;
            tr[i].lazy+=val;
            return ;
        }
        Pushdown(i);
        int mid=(tr[i].l+tr[i].r)>>1;
        if(pos<=mid) Update(pos,val,i<<1);
        else Update(pos,val,i<<1|1);
        Pushup(i);
    }
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for (int op,a,b,i=1; i<=m; i++){
            scanf("%d",&op);
            scanf("%d%d",&a,&b);
            if(!op) Update(a,b,1);
            else printf("%lld
    ",Query(a,b,1));
        }
        return 0;
    }

    树状数组做法:
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=4e5+10;
    typedef long long ll;
    ll tree[maxn],n,m;
    inline int lowbit(int x){return x&-x;}
    inline void Update(int x,int val){ for (int i=x; i<=n; i+=lowbit(i)) tree[i]+=val; }
    inline ll Query(int x){
        ll res=0;
        for (int i=x; i; i-=lowbit(i)) res+=tree[i];
        return res;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int op,a,b,i=1; i<=m; i++){
            scanf("%d",&op);
            scanf("%d%d",&a,&b);
            if(!op) Update(a,b);
            else printf("%lld
    ",Query(b)-Query(a-1));
        }
        return 0;
    }
     

     

  • 相关阅读:
    韦到头打印链表
    字符串替换
    二维数组中的查找
    字符串加解密
    简单密码破解
    vue中store模块化
    使用requests抓取网页内容
    PyQt中的一些小问题
    微信公众号之Token验证
    编译BOOST中的PYTHON模块
  • 原文地址:https://www.cnblogs.com/acerkoo/p/9495484.html
Copyright © 2011-2022 走看看