1264. 动态求连续区间和 树状数组 线段树

  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,
数据保证在任何时候,数列中所有元素之和均在 int 范围内。

输入样例:
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

树状数组

import java.util.*;

public class Main
{
    static int n,m,tr[]=new int[100005],a[]=new int[100005],x,y,k;
    public static void main(String []args)
    {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        for(int i=1;i<=n;++i)a[i]=sc.nextInt();
        for(int i=1;i<=n;++i)add(i,a[i]);
        while((m--)>0)
        {
            k=sc.nextInt();
            x=sc.nextInt();
            y=sc.nextInt();
            if(k==0)System.out.println(query(y)-query(x-1));
            else add(x,y);
        }
    }
    static int lowbit(int x)
    {
        return x&-x;
    }
    static void add(int x,int v)
    {
        for(int i=x;i<=n;i+=lowbit(i))tr[i]+=v;
    }
    static int query(int x)
    {
        int res=0;
        for(int i=x;i>0;i-=lowbit(i))res+=tr[i];
        return res;
    }
}

线段树

import java.util.*;

public class Main 
{
    static int n,m,k,x,y,N=100005,w[]=new int [N];
    static class node
    {
        int l,r,sum;
    }
    static node tr[]=new node[4*N];

    static void pushup(int u)
    {
        tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
    }

    static void build(int u,int l,int r)
    {
        tr[u]=new node();
        tr[u].l=l;
        tr[u].r=r;
        if(l==r)tr[u].sum=w[r];
        else
        {
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    static int query(int u,int l,int 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;
    }
    static void modify(int u,int x,int 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);
        }
    }
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        for(int i=1;i<=n;++i)w[i]=sc.nextInt();
        build(1,1,n);

        while((m--)>0)
        {
            k=sc.nextInt();
            x=sc.nextInt();
            y=sc.nextInt();
            if(k==0)System.out.println(query(1,x,y));
            else modify(1,x,y);
        }
    }
}

posted @ 2022-11-17 23:01  林动  阅读(6)  评论(0编辑  收藏  举报