zoukankan      html  css  js  c++  java
  • 【模板】树状数组2

    题目描述

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

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

    2.求出某一个数的值

    输入格式

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含2或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x 含义:输出第x个数的值

    输出格式

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入 #1
    5 5
    1 5 4 2 3
    1 2 4 2
    2 3
    1 1 5 -1
    1 3 5 7
    2 4
    输出 #1
    6
    10

    说明/提示

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=10000,M<=10000

    对于100%的数据:N<=500000,M<=500000

    样例说明:

    故输出结果为6、10

    #include <bits/stdc++.h>
    #define lowbit(i) (i&-i)
    using namespace std;
    const int Q=500005;
    int A[Q];
    int bit[Q];
    int n,m;
    
    void modify(int i,int x){
        while(i<=n){
            bit[i]+=x;
            i+=lowbit(i);
        }
    }
    
    int query(int i){
        int res=0;
        while(i>0){
            res+=bit[i];
            i-=lowbit(i);
        }
        return res;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&A[i]);
        }
        for(int i=1;i<=n;i++){
            modify(i,A[i]),modify(i+1,-A[i]);
        }
        while(m--){
            int opt;
            scanf("%d",&opt);
            if(opt==1){
                int l,r,x;
                scanf("%d%d%d",&l,&r,&x);
                modify(l,x);
                modify(r+1,-x);
            }
            else{
                int x;
                scanf("%d",&x);
                printf("%d
    ",query(x));
            }
        }
        return 0;
    }
  • 相关阅读:
    7月15日考试 题解(链表+状压DP+思维题)
    暑假集训日记
    C# .NET 使用 NPOI 生成 .xlsx 格式 Excel
    JavaSE 基础 第42节 局部内部类
    JavaSE 基础 第41节 匿名内部类
    JavaSE 基础 第40节 内部类概述
    JavaSE 基础 第39节 接口的应用
    JavaSE 基础 第38节 接口的实现
    JavaSE 基础 第37节 接口概述
    JavaSE 基础 第36节 抽象类概述与使用
  • 原文地址:https://www.cnblogs.com/hrj1/p/11197408.html
Copyright © 2011-2022 走看看