树状数组 区间更新 POJ3468
2017-03-11 05:46
260 查看
POJ3468https://vjudge.net/problem/POJ-3468
学习了树状数组后看到书上还有关于它的区间更新知识点,书上给的不是很明确。我在网上找了一下发现了一种相对来说好理解的方法。在此总结。
因为初学,所以我要从头回顾一下树状数组的知识点。
兄弟关系:
明日再更。
学习了树状数组后看到书上还有关于它的区间更新知识点,书上给的不是很明确。我在网上找了一下发现了一种相对来说好理解的方法。在此总结。
因为初学,所以我要从头回顾一下树状数组的知识点。
先说明lowit.在树状数组中lowbit是一个很重要的东西。他能清二进制数的高位1,保留最低位1.比如6->0110 ,用lowbit求出后得到了0010.常用的lowbit求法#define lowbit(x) (x&-x) 我把节点之间的关系定义为两种,一种叫父子一种叫兄弟关系。 父子关系: C5的父节点是C6,C6的父节点是C8,5->0101,6->0110,8->1000.子节点通过加上本身的lowbit值得到其父节点节点值。0101+0001=0110,0110+0010=1000. 这种关系用来更新某节点值。当5点更新,立刻通过他的lowbit找到父节点并更新直到不能更新为止。
void add(LL arr[],LL x, LL d){ while (x <= n){ arr[x] += d; x += lowbit(x); } }
兄弟关系:
明日再更。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<string>
#include<stdlib.h>
#include<limits.h>
using namespace std;
/******************************************************/
#define LL long long int
#define mem(a,b) memset(a,b,sizeof(a))
#define m ((l+r)/2)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define L rt<<1
#define R rt<<1|1
#define N 400000+1
#define pow(a) a*a
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define lowbit(x) (x&-x)
/*********************************************************/
/*sum[x] = org[1]+...+org[x] + delta[1]*x +
delta[2]*(x-1) + delta[3]*(x-2)+...+delta[x]*1
= org[1]+...+org[x] + segma(delta[i]*(x+1-i))
= segma(org[i]) + (x+1)*segma(delta[i]) - segma(delta[i]*i),1 <= i <= x*/
/***************************************************/
/*10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4*/
LL n, q;
LL dat
;
LL summ
;
LL bit0
, bit1
;
char s[2];
void add(LL arr[],LL x, LL d){ while (x <= n){ arr[x] += d; x += lowbit(x); } }
LL find(LL x,LL su[]){
LL res = 0;
while (x > 0){
res += su[x];
x -= lowbit(x);
}
return res;
}
int main(){
mem(summ, 0);
mem(bit0, 0);
mem(bit1, 0);
scanf("%lld%lld", &n, &q);
for (int i = 1; i <= n; i++)scanf("%lld", &dat[i]);
summ[0] = 0;
for (int i = 1; i <= n; i++){
summ[i] = summ[i - 1] + dat[i];
}
while (q--){
LL a, b;
scanf("%s%lld%lld", s, &a, &b);
if (s[0] == 'Q'){
LL sum = summ[b] - summ[a - 1];
LL sum1 =(b+1)* find(b, bit0) - find(b, bit1);
LL sum2 = a*(find(a - 1, bit0)) - find(a - 1, bit1);
printf("%lld\n", sum + sum1 - sum2);
}
else{
LL c; scanf("%lld", &c);
add(bit0, a, c);
add(bit0, b + 1, -c);
add(bit1, a, c*a);
add(bit1, b + 1, -c*(b + 1));
}
}
}
相关文章推荐
- poj3468 树状数组的区间快速更新和查询
- POJ3468 树状数组的区间更新和区间求和
- poj3468 树状数组(区间更新)
- 三维树状数组(区间更新,单点查询)POJ
- HDU - 4777 Rabbit Kingdom 预处理 + 树状数组(区间更新点查询)
- poj3468-树状数组 一维 区间更新 区间查询
- HDU 1166 敌兵布阵 数据结构+树状数组+(单点更新区间求和)
- 01变换 二维树状数组+区间更新,单点查询 poj 2155 Matrix
- HDU 6203 ping ping ping LCA + dfs序 + 树状数组(区间更新单点查询)
- POJ3468 线段树(区间更新,区间求和,延迟标记)
- POJ3468(线段树之区间更新)
- 线段树 区间更新 访问POJ3468 A Simple Problem with Integers解题报告
- POJ3468 线段树 区间更新
- 线段树(4)--poj3468(区间更新 延迟更新)
- POJ 2155 Matrix(二维树状数组+数组数组区间更新+单点查询)
- 树状数组模板区间更新 区间询问
- H - Color the ball(树状数组)(区间更新)(求单点)(线段树)
- poj3468 A Simple Problem with Integers 线段树区间更新
- POJ3468 A simple problem with integers(区间更新)
- POJ3468(线段树区间更新)