卧槽

厉害了,我的树状数组

1、单点修改,单点查询

  用差分数组维护

#include<cstdio>
#include<iostream>
using namespace std;
#define int long long
#define M 1000500
#define love_nmr 0
#define lowbit(x) (x&(-x))
int c[M],flag,n,m;
inline void add(int pos,int x)
{
for(int i=pos;i<=n;i+=lowbit(i))
c[i]+=x;
}
inline int query(int x)
{
int ans=;
for(int i=x;i;i-=lowbit(i))
ans+=c[i];
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int now=,last=;
for(int i=;i<=n;i++)
{
cin>>now;
add(i,now-last);
last=now;
}
int x;
for(int i=;i<=m;i++)
{
cin>>flag;
if(flag==)
{
int x,k;
cin>>x>>k;
add(x,k);
add(x+,-k);
}
else
{
cin>>x;
cout<<query(x)<<endl;
}
}
return love_nmr;
}

2、单点修改,区间查询(最原始的,最本质的)

#include<cstdio>
#include<iostream>
using namespace std;
#define N 1000050
#define int long long
#define love_nmr 0
int a[N],c[N],j;
int n,m;
inline int lowbit(int x)
{
return x&(-x);
}
inline void add(int x,int y)
{
while(x<=n)
{
c[x]+=y;
x+=lowbit(x);
}
}
inline int sum(int x)
{
int ace=;
while(x>=)
{
ace+=c[x];
x-=lowbit(x);
}
return ace;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int x,y;
for(int i=;i<=n;i++)
{
cin>>a[i];
add(i,a[i]);
}
for(int i=;i<=m;i++)
{
cin>>j>>x>>y;
if(j==)
add(x,y);
else
cout<<sum(y)-sum(x-)<<endl;
}
return love_nmr; }

3、区间修改,单点查询

  差分应用

#include<cstdio>
#include<iostream>
using namespace std;
#define int long long
#define M 1000500
#define love_nmr 0
#define lowbit(x) (x&(-x))
int c[M],flag,n,m;
inline void add(int pos,int x)
{
for(int i=pos;i<=n;i+=lowbit(i))
c[i]+=x;
}
inline int query(int x)
{
int ans=;
for(int i=x;i;i-=lowbit(i))
ans+=c[i];
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int now=,last=;
for(int i=;i<=n;i++)
{
cin>>now;
add(i,now-last);
last=now;
}
int x;
for(int i=;i<=m;i++)
{
cin>>flag;
if(flag==)
{
int x,y,k;
cin>>x>>y>>k;
add(x,k);
add(y+,-k);
}
else
{
cin>>x;
cout<<query(x)<<endl;
}
}
return love_nmr;
}

4、区间修改,区间查询(niubilitiful)

观察式子:
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[n],其中c2[i] = (i-1)*c[i]

每当修改c的时候,就同步修改一下c2,这样复杂度就不会改变

那么

式子①

$=n*\sum{(c,n)} - \sum{(c2,n)}$

于是我们做到了在O(logN)的时间内完成一次区间和查询

#include<cstdio>
#include<iostream>
using namespace std;
#define int long long
#define M 1000500
#define love_nmr 0
#define lowbit(x) (x&(-x))
int c[M],flag,n,m;
int s[M];
inline void add(int pos,int x)
{
for(int i=pos;i<=n;i+=lowbit(i))
{
c[i]+=x;
s[i]+=(pos-)*x;
}
}
inline int queryc(int x)
{
int ans=;
for(int i=x;i;i-=lowbit(i))
ans+=c[i];
return ans;
}
inline int querys(int x)
{
int ans=;
for(int i=x;i;i-=lowbit(i))
ans+=s[i];
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int now=,last=;
for(int i=;i<=n;i++)
{
cin>>now;
add(i,now-last);
last=now;
}
for(int i=;i<=m;i++)
{
cin>>flag;
if(flag==)
{
int x,y,k;
cin>>x>>y>>k;
add(x,k);
add(y+,-k);
}
else
{
int x,y;
cin>>x>>y;
int tot1=y*queryc(y)-querys(y);
int tot2=(x-)*queryc(x-)-querys(x-);
cout<<tot1-tot2<<endl;
}
}
return love_nmr;
}

一件很好的事情就是树状数组的常数比其他NlogN的数据结构小得多,实际上它的计算次数比NlogN要小很多,再加上它代码短,是OI中的利器

厉害了~~~~~

树状数组的神操作QAQ的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  2. {POJ}{树状数组}

    总结一下树状数组的题目: {POJ}{3928}{Ping Pong} 非常好的题目,要求寻找一个数组中满足A[i]<A[k]<A[j]的个数,其中i<k<j(或者相反).很巧 ...

  3. POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)

    树状数组求逆序对   转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...

  4. 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...

  5. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

    题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...

  6. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

    转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...

  7. Stars(二维树状数组)

    Stars Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others) Total Submiss ...

  8. luogu 4145 花神游历各国 线段树/树状数组+并查集

    此题一看便是RMQ问题,但是由于开平方的特殊操作,tag操作失效 此时发现特性:sqrt最多执行6此便使值到达1/0,此时可以剪枝不进行该操作,利用并查集到达特性找根,根代表还可以进行操作的点,再利用 ...

  9. 牛客第二场-J-farm-二维树状数组

    二维树状数组真的还挺神奇的,更新也很神奇,比如我要更新一个区域内的和,我们的更新操作是这样的 add(x1,y1,z); add(x2+1,y2+1,z); add(x1,y2+1,-z); add( ...

随机推荐

  1. 如何更好的理解js中的this,分享2段有意思的代码

    关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...

  2. 06 - Django应用第三步

    知识点 1) 编写urls 配合include()的URL查找过程 获取正则抓取的值并命名, 给url取名 2) 模板的编写 for循环的遍历 用点的方式执行函数, 不带括号 3) 视图函数的编写 H ...

  3. Java Modifiers

    Private means this could only be seen within this class. Protected means "package private" ...

  4. Maven(6)-POM

    to be continued.

  5. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  6. 时间倒计时 JS

    <div id="keleyi">Christmas Countdown</div> <script type="text/javascri ...

  7. js获取集合对象的个数

    代码: var t={"a":"1","b":'2'}; alert(Object.keys(t).length); 用处:可用于集合对象的 ...

  8. C#图片压缩类winform

    using System;using System.Collections.Generic;using System.Text;using System.Drawing;using System.Dr ...

  9. django examples 学习笔记(1)创建一个独立的python环境

    pip install virtualenv   创建一个虚拟环境 virtualenv   my_env      创建一个独立的环境 source my_env/bin/activate   激活 ...

  10. .clearfix:after

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...