未解决的树状数组差分(改变区间,求单点值)

// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define inf 500001
#define lll long long int
using namespace std;
long c[inf],a,n,m,k,xx,nn;
int lowbit(int x){
	return x&(-x);//求X二进制下从右到左第一个1的所对应的十进制下的值
}
void update(int x,int y){//update添加修改之意
		while(x<=n){
		c[x]+=y;//c[i]树状数组
		x+=lowbit(x);
		}
	}

int sum(int x){
	int sm=0;
	while(x>0){
		sm+=c[x];
		x-=lowbit(x);//注意顺序不能颠倒
	}
	return sm;
}
int main(){
ios::sync_with_stdio(0);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%d",&a);
	update(i,a-nn);
	nn=a;
}

for(int i=1;i<=m;i++){
	scanf("%d",&k);
	int aa,bb,cc;
	if(k==1){
	scanf("%d %d %d",&aa,&bb,&cc);
		update(aa,cc);
		update(bb+1,-cc);
	}
    if(k==2){
    scanf("%d",&aa);
	printf("%d\n",sum(aa));
	}
}
return 0;
}

  

原文地址:https://www.cnblogs.com/sc-pyt-2021-theworld/p/10426513.html

时间: 2024-08-01 07:28:19

未解决的树状数组差分(改变区间,求单点值)的相关文章

树状数组模板(区间修改+单点查询)

很巧妙的用了差分建树,解决区间修改的问题 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=5e5+5; 5 6 int n,m; 7 int a[maxn]; 8 ll tree[maxn]; 9 10 int lowbit(int x){ 11 return x&(-x); 12 } 13 14 void add(int idx,int v){ 15

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

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

POJ2155/LNSYOJ113 Matrix【二维树状数组+差分】【做题报告】

这道题是一个二维树状数组,思路十分神奇,其实还是挺水的 题目描述 给定一个N∗NN∗N的矩阵AA,其中矩阵中的元素只有0或者1,其中A[i,j]A[i,j]表示矩阵的第i行和第j列(1≤i,j≤N)(1≤i,j≤N),初始矩阵元素都是0.在矩阵上进行TT次操作,操作有以下两种: (1)格式为C x1 y1 x2 y2(1≤x1≤x2≤n,1≤y1≤y2≤n)C x1 y1 x2 y2(1≤x1≤x2≤n,1≤y1≤y2≤n) ,其中CC为字符“C”,表示把以(x1,y1)(x1,y1)为左上角,

树状数组差分求前缀和的前缀和

既然我们知道树状数组可以差分求前缀和 那么就可以对其进行 前缀和 求变量值 展开可得 $(k+1)*\sum_{i}^n c[i]-\sum_{i}^n i*c[i]$ 两个 树状数组可以搞定 顺便提一下DFS序  可以将树上问题转化为区间问题 对节点重新编号 并且有从属关系  从而 利用各种数据结构 例如 树剖  树状数组解决 原文地址:https://www.cnblogs.com/OIEREDSION/p/11380443.html

bzoj2743: [HEOI2012]采花--离线树状数组+差分

题目大意:给定一个区间,查询子区间里出现次数不小于二的数的个数 此题想了好久没想出来,后来是在网上学习的一个方法 首先按查询区间的右端点进行排序,按右端点从小到大处理 假设pre[a[i]]是与a[i]相同的前一个数的位置,记为left[i] 当查询到第i个数时,对left[left[i]]+1~left[i]的每个数的权值w[]加1 也就是说:左端点在left[left[i]]+1~left[i]内,右端点为i的区间里,出现次数不小于二的数+1 那么对于查询i,答案就是w[left[i]] 因

树状数组模板(改点求段 / 该段求点 / 改段求段)

1. 改点求段(单点更新, 区间求和) 代码: 1 #include <iostream> 2 using namespace std; 3 4 const int MAXN = 1e5 + 10; 5 int tree[MAXN], n; 6 7 int lowbit(int x){//返回 pow(2, k),其中k为末尾0的个数, 即返回最低位1的值 8 return x & -x; 9 } 10 11 void add(int x, int d){//将d累加到tree数组对应

树状数组的改段求点,改段求段

改段求点(区间更新, 单点求值) 用一个数组 d 存储目标数组 a 中相邻元素的差值, 即 i > 1 时, d[i] = a[i] - a[i - 1] ; i == 1 时, d[i] = a[i] . 那么有 a[i] = d[1] + ... + d[i] .若要将 a 数组区间 [l, r] 的元素都加上 key, 显然只需令 d[l] += key, d[r + 1] -= key 即可. 显然只要用树状数组维护一下 d 数组即可. 改段求段(区间更新,区间求值) 与上面类似, 先开

HDU1556 Color the ball【树状数组】【区间更新】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1556 题目大意: N个气球排成一排,从左到右编号为1~N,给N组数据,每次给2两个整数s,e,表示从s到e将 气球涂色.当涂到N次以后已经忘记了第i个气球被涂过几次颜色了.现在来计算出每个气球被 涂了几次颜色,并输出出来. 思路: 典型的更新区间,单点求值问题.直接模拟会超时,考虑用树状数组来做.单点更新中,树状 数组表示区间的和.在区间更新中,树状数组表示单个元素的变化. 这道题中,区间(s,e

A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267

A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4032    Accepted Submission(s): 1255 Problem Description Let A1, A2, ... , AN be N elements. You need to deal with