树状数组的建树 单点修改 单点查询 区间修改 区间查询

单点修改  单点查询   用普通数组就能写出来

单点修改  区间查询   用线段树  树状数组;

区间修改  区间查询   用线段树  树状数组;

区间修改  单点查询   用线段树  树状数组;

建树

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node
{
    int l,r,w;
}tree[4*maxn+1];
void build(int l,int r,int k)
{
    tree[k].l=l; tree[k].r=r;
    if(l==r)  { cin>>tree[k].w; return ; }
    int mid=(l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int main()
{
    build(1,8,1);
}

建树

单点查询

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node
{
    int l,r,w;
}tree[4*maxn+1];
void build(int l,int r,int k)
{
    tree[k].l=l; tree[k].r=r;
    if(l==r)  { cin>>tree[k].w; cout<<l<<"--"<<tree[k].w<<endl; return ; }
    int mid=(l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int ask(int x,int k)// dian dian cha xun;
{
   if(tree[k].l==tree[k].r) {return tree[k].w; }
   int mid=(tree[k].l+tree[k].r)/2;
   if(x<=mid) return ask(x,2*k);
   else       return ask(x,2*k+1);

}
int main()
{
    build(1,8,1);
    //for(int i=1;i<=8;i++) cout<<"=="<<ask(i)<<endl;
    cout<<ask(1,1)<<endl;
    cout<<ask(7,1)<<endl;
}

单点查询

原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/9715315.html

时间: 2024-08-28 16:53:55

树状数组的建树 单点修改 单点查询 区间修改 区间查询的相关文章

树状数组 小白篇(2)暨区间修改

这篇主要来讲一讲树状数组的区间修改 因为一个一个点改,毫无疑问耗时太长 所以,机智的人类YY出了用差分来表示数组 为了便于理解,简单一点数组{an}:a[1]=0, a[2]=0, a[3]=0, a[4]=0, a[5]=0, a[6]=0 ,a[7]=0, a[8]=0, a[9]=0 用差分思想,delta[x]表示a[x]-a[x-1] 显然,一开始delta[]=0 我们先计算出前n项和{sn}来 然后别眨眼,下面就是见证奇迹的时刻! 有个分界线显得正式一点 我们要把a[3]到a[6]

Wikioi 2492 树状数组+并查集(单点更新区间查询)

刚开始做的时候用线段树做的,然后就跳进坑里了--因为要开方,所以区间的值都得全部变,然后想用lazy标记的,但是发现用不了,单点更新这个用不了,然后就不用了,就T了.然后实在不行了,看了别人的题解,原来是用树状数组+并查集的方法,唉--没想到啊! 因为开方之后多次那个数就会变成1了,所以是1的时候开方下去就没用了.树状数组更新的时候就把其更新的差更新即可,太机智了这题-- 昨天做了,然后出错找了好久都找不出来,原来是把s[i]写成c[i]了,然后答案一直错,晕-- #include <iostr

POJ2155 Matrix 【二维树状数组】+【段更新点查询】

Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17766   Accepted: 6674 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1

洛谷 P3374 【模板】树状数组 1 如题(单点修改+区间查询)

P3374 [模板]树状数组 1 时空限制1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x k 含义:将第x个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内

树状数组区间修改,区间更新:差分数组的运用

树状数组最原始的作用就是求前缀和,可以实现单点修改和区间查询. 但是假设现在有: 1.区间修改,单点查询 2.区间修改,区间查询 但是又不想敲线段树怎么办? 就用树状数组喽. 假设现在有一个原数组a(假设a[0] = 0),有一个数组d,d[i] = a[i] - a[i-1],那么 a[i] = d[1] + d[2] + .... + d[i] d数组就是差分数组 所以求a[i]就可以用树状数组维护d[i]的前缀和 区间修改,单点查询: 根据d的定义,对[l,r]区间加上x,那么a[l]和a

树状数组的区间修改与单点查询与区间查询

如何将普通树状数组升级 普通的单点修改单点查询就不讲了,从区间修改和单点查询讲起. 原来的值存在a[]里面,多建立个数组c1[],注意:c1[i]=a[i]-a[i-1]. 那么求a[i]的值的时候a[i]=a[i-1]+c1[i]=a[i-2]+c1[i]+c1[i-1]=-..=c1[1]+c1[2]+-+c1[i]. 所以就用c1[]建立树状数组,便可以很快查询a[i]的值.不多说,见代码. #include<iostream> #include<cstdio> #defin

【树状数组区间修改区间求和】codevs 1082 线段树练习 3

http://codevs.cn/problem/1082/ [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=2e5+2; 5 int n; 6 ll a[maxn]; 7 ll c1[maxn]; 8 ll c2[maxn]; 9 int lowbit(int x) 10 { 11 return x&-x; 12 } 13 void add(l

树状数组—模板整理

树状数组整理 update 更新 1.单点更新,将第p个数增加v 1 void update(int p,int v) //将第P个数增加v 2 { 3 while(p<=n) 4 { 5 sum[p] += v; 6 p += lowbit(p); 7 } 8 } 2.区间更新,将区间[x,y]增加v 1 void inerval_update(int x,int y,int v) //区间修改—[x,y]的区间增加v 2 { 3 update(x,v); 4 update(y+1,-v);

树状数组 线段树

树状数组 树状数组的基本用途是维护序列的前缀和,相比前缀和数组,树状数组优势在于高效率的单点修改,单点增加(前缀和数组单点修改效率比较低) 因为树状数组的思想,原理还是很好理解的,就直接讲基本算法; 1 lowbit函数 关于lowbit这个函数,可能会有点难以理解,但其实你不理解也没关系,把模板背下来就好 根据任意正整数关于2的不重复次幂的唯一分解性质,例如十进制21用二进制表示为10101,其中等于1的位是第0,2,4(最右端是第0位)位,即21被二进制分解成\(2^4+2^2+2^0\);