树状数组实现 区间修改+区间查询
来源:互联网 发布:矢仓枫子 知乎 编辑:程序博客网 时间:2024/05/22 05:00
树状数组的本职:单值修改+区间查询
对于区间修改 首先想到的就是线段树 可是线段树的代码太tm长了 是真的懒得写 然后就学习了一下如何用树状数组实现 区间修改+区间查询
差分数组
对于一个数组a 其差分数组定义为 C[i] = a[i] - a[i-1]( i>0 )&&C[0] = a[0]
我们很容易看出 a[i] = C[0]+C[1]+C[2]+......+C[i]
然后 我们想实现区间修改就可以借助差分数组实现
如果我们要实现对数组a 区间 [l,r]内的元素 +v
借助差分数组 只需使 C[l]+=v,C[r+1] -=v 即可
为什么可以这样实现呢 我们来看式子
a[1]+a[2]+...+a[n]
= (c[1]) + (c[1]+c[2]) + ... + (c[1]+c[2]+...+c[n])
= n*c[1] + (n-1)*c[2] +... +c[n]
= n * (c[1]+c[2]+...+c[n]) - (0*c[1]+1*c[2]+...+(n-1)*c[n])
由公式可以发现 我们要进行区间修改和区间查询只需要再维护一个数组 C2[i] = (i-1)*C[i]
对于 a[1]+a[2]+...+a[n] = n*read(C,n) - read(C2,n)
这样就可以进行区间修改和区间查询操作做了 因为我们同时进行修改数组C,C2 所以复杂度还是n*log(n)
而且比线段树快得多
题目链接:http://codevs.cn/problem/1082/
代码实现:
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <map>#include <set>#include <vector>#include <algorithm>#include <stack>#include <queue>#include <math.h>#include <bitset>#include <climits>using namespace std; typedef long long ll;const int maxn=200000+10;ll D1[maxn];ll D2[maxn];ll num[maxn];ll n;void add(ll D[],int k,ll num){while (k<=n){D[k]+=num;k+=(k&-k);}}ll read(ll D[],ll k){ll sum=0;while (k){sum+=D[k];k-=(k&-k);}return sum;}int main (){scanf ("%lld",&n);for (int i=1;i<=n;i++){scanf ("%lld",&num[i]);add(D1,i,num[i]-num[i-1]);add(D2,i,(i-1)*(num[i]-num[i-1]));}ll t;scanf ("%lld",&t);while (t--){ll m;scanf ("%lld",&m);if(m==1){ll l,r,v;scanf ("%lld%lld%lld",&l,&r,&v);add(D1,l,v);add(D1,r+1,-v);add(D2,l,v*(l-1));add(D2,r+1,-v*r);}else{ll l,r;scanf ("%lld%lld",&l,&r);ll sum1=(l-1)*read(D1,l-1)-read(D2,l-1);ll sum2=r*read(D1,r)-read(D2,r);printf ("%lld\n",sum2-sum1);}}return 0;}
- 树状数组实现 区间修改+区间查询
- 树状数组~poj3468~区间修改 区间查询
- 树状数组 --区间查询+区间修改
- 【codevs1082】【树状数组】 区间修改 区间查询
- 笔记 树状数组--区间查询+区间修改
- 树状数组区间修改区间查询
- 树状数组 区间修改+区间查询
- 树状数组区间修改区间查询
- 树状数组 区间修改 区间查询
- 树状数组 区间修改查询
- 树状数组区间修改+查询
- 树状数组(单点修改区间查询、区间修改单点查询、区间修改区间查询)
- 树状数组-单点修改区间查询-区间修改单点查询-区间修改区间查询
- 【树状数组】区间修改&点查询
- 【树状数组】点修改&区间查询
- 树状数组的区间修改,单点查询
- hdu1556 树状数组 区间修改,点查询
- 【codevs1080】【树状数组】 单点修改 区间查询
- ORACLE 中的 ROW_NUMBER() OVER() 分析函数的用法
- String,StringBuffer与StringBuilder的区别
- 树链剖分
- 【转】前端框架基础:Babel & package.json & npm & nodemon
- 一位数组>>>>>>>>>>约瑟夫环
- 树状数组实现 区间修改+区间查询
- HDU-2017 多校训练赛4-1004-Dirt Ratio
- python多线程
- B
- 中大型网站架构的演变之路
- 自定义view继承view
- Oracle 分组函数
- G
- cf632e dp