首页 > 其他分享 >树状数组

树状数组

时间:2023-08-03 13:44:06浏览次数:30  
标签:cnt return 树状 int lowbit long 数组 include

log(n)修改,log(n)查询

可以顶替掉一部分线段树的作用,而且码量十分友好

但是对我来说是有点难理解的,现在只是大体理解,没有很通透,所以不写自己的理解了,以后要多看看

1.单点修改区间查询

https://blog.csdn.net/ls2868916989/article/details/119268741

代码(P3374):

#include<iostream>
#include<cstdio>
using namespace std;
const long long N=1e6+10;
int n,m,u,v,w,a[N];
int c[N];
int lowbit(int x){
    return x&(-x);
}
void change(int x,int y){
    while(x<=n){
        c[x]+=y;
        x+=lowbit(x);
    }
}
int print(int x){
    int cnt=0;
    while(x>0){
        cnt+=c[x];
        x-=lowbit(x);
    }
    return cnt;
}
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++){
        int h=i;
        while(h<=n){
            c[h]+=a[i];
            h+=lowbit(h);
        }
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        if(u==1) change(v,w);
        else printf("%d\n",print(w)-print(v-1));
    }
    return 0;
}

2.区间修改单点查询

去看这篇博客!!写的超级无敌好  https://www.cnblogs.com/daybreaking/p/9408301.html

大概的意思就是搞一个差分数组,修改的时候直接头尾一加一减,单点查询的时候要逐个相加

代码(P3374):

#include<iostream>
#include<cstdio>
using namespace std;
const long long N=1e6+10;
int n,m,a[N],d[N];
int c[N],k,u,v,w;
int lowbit(int x){
    return x&(-x);
}
void change(int x,int y){
    while(x<=n){
        c[x]+=y;
        x+=lowbit(x);
    }
}
int print(int x){
    int cnt=0;
    while(x>0){
        cnt+=c[x];
        x-=lowbit(x);
    }
    return cnt;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        d[i]=a[i]-a[i-1];
    }
    for(int i=1;i<=n;i++){
        int h=i;
        while(h<=n){
            c[h]+=d[i];
            h+=lowbit(h);
        }
    }
    for(int i=1;i<=m;i++){
        scanf("%d",&k);
        if(k==1){
            scanf("%d%d%d",&u,&v,&w);
            change(u,w);
            change(v+1,-w);
        }
        else{
            scanf("%d",&u);
            printf("%d\n",print(u));
        }
    }
    return 0;
}

 

标签:cnt,return,树状,int,lowbit,long,数组,include
From: https://www.cnblogs.com/dgdger/p/17603110.html

相关文章

  • 无涯教程-Perl - Arrays(数组)
    数组是一个变量,用于存储标量值的有序列表。数组变量前面有一个“@”符号。要引用数组的单个元素,将使用带符号名称的美元符号($),后跟方括号中的元素索引,这是使用数组变量的简单示例-#!/usr/bin/perl@ages=(25,30,40);@names=("JohnPaul","Lisa","Kumar");......
  • (*)LeetCode 热题 100 之 238. 除自身以外数组的乘积
    题目给你一个整数数组nums,返回数组answer,其中answer[i]等于nums中除nums[i]之外其余各元素的乘积。题目数据保证数组nums之中任意元素的全部前缀元素和后缀的乘积都在32位整数范围内。请不要使用除法,且在O(n)时间复杂度内完成此题。示例1:输入:nums=......
  • 剑指 Offer 03. 数组中重复的数字(简单)
    题目;classSolution{public:intfindRepeatNumber(vector<int>&nums){intresult;unordered_set<int>set;//利用集合寻找重复的数字for(auton:nums){if(set.find(n)==set.end()){//如果set里没找到就加入set......
  • 剑指 Offer 53 - I. 在排序数组中查找数字 I(简单)
    题目:classSolution{public:intsearch(vector<int>&nums,inttarget){intcount=0;for(auton:nums){if(n==target){count++;}}returncount;}};......
  • 修改数组
    传送门思路首先想到的是用一个集合来记录出现过的数字,每次每次查询的时间复杂度为O(1),本来以为可以直接过的,没想到只能拿到40分n=int(input())arr=[int(n)fornininput().split()]#用来记录出现过的数字s=set()foriinrange(n): #一直累加,直到没有出现过......
  • C语言逆向——数组和结构体,数组多维只是一个编译构造的假象,本质会转成一维数组,结构体
    数组数组是C语言中非常重要的一个概念,学习C语言主要就是两个知识点:数组、指针,学好这两个,那么你的C语言一定也会很好。什么是数组?或者说什么情况下我们需要使用数组,比如说我们需要定义一个人的年龄,我们可以定义一个变量来表示,但是如果我们需要定义三个人的年龄呢?那就需要三个变量来......
  • LeetCode 热题 100 之 189. 轮转数组
    题目给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。示例1:输入:nums=[1,2,3,4,5,6,7],k=3输出:[5,6,7,1,2,3,4]解释:向右轮转1步:[7,1,2,3,4,5,6]向右轮转2步:[6,7,1,2,3,4,5]向右轮转3步:[5,6,7,1,2,3,4]示例2:输入:nums=......
  • 数组去重的方法
    1、双重for循环+splice()思路:数组的splice()方法删除当前重复元素,第一个参数是开始的值,第二个参数是需要删除的个数。letarr=["a","the","a","b","test","good","the","a","good","a"]......
  • PHPHashtable 如何优化数组查找和排序
    PHPHashtable如何优化数组查找和排序PHP是一种高度流行的编程语言,被广泛用于web开发。它有很多的优点,例如易于学习、跨平台、简单易用的语法等等。而在PHP中,数组是一种非常常用的数据结构,它可以存储一组有序的数据,方便我们进行各种操作。PHPHashtable如何优化数组查找和排......
  • 后缀数组(SA)做题记录
    SA真的是个好东西,好呀好东西。基础定义:$sa$数组:后缀排序后排名为$i$的后缀的起始位置下标。$rk$数组:起始下标为$i$的后缀的排名。$height$数组:后缀排序后排名为$i$和$i-1$的最长公共前缀长度(Lcp)模板:(小bug:在SA代码charch[N];structSuffix_Array{llm=......