树状数组模板
【模板】树状数组 1 点我
代码:
#include <iostream>
using namespace std;
int c[500001],n,m,t1,t2,t3;
int lowbit(int x)
{
return x&-x;
}
void update(int x,int k)
{
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=k;
}
int sum(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
{
cin >> t1;
update(i,t1);
}
for(int i=1;i<=m;i++)
{
cin >> t1 >> t2 >> t3;
if(t1==1)
update(t2,t3);
if(t1==2)
cout << sum(t3)-sum(t2-1) << endl;
}
return 0;
}
【模板】树状数组 2 点我
代码:
#include <iostream>
using namespace std;
int c[500001],n,m,t1,t2,t3,t4;
int lowbit(int x)
{
return x&-x;
}
void update(int l,int r,int k)
{
for(int i=l;i<=n;i+=lowbit(i))
c[i]+=k;
for(int i=r+1;i<=n;i+=lowbit(i))
c[i]-=k;
}
int sum(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
{
cin >> t1;
update(i,i,t1);
}
for(int i=1;i<=m;i++)
{
cin >> t1 >> t2;
if(t1==1)
{
cin >> t3 >> t4;
update(t2,t3,t4);
}
if(t1==2)
cout << sum(t2) << endl;
}
return 0;
}
关于lowbit:
大家看看这张图,我列举出了各个元素的lowbit值。我们可以发现,lowbit(x)=father(x)-x。father[x]代表x的父亲(比如图中1的父亲是2,3的父亲是4,6的父亲是8)。
另外我们还可以发现,lowbit(x)=x-lastbrother(x)。lastbrother(x)代表x的前一个兄弟。如果x是第一个兄弟,则lastbrother(x)=0。
比如图中4的前一个兄弟是0,6的前一个兄弟是4,7的前一个兄弟是6。
树状数组在没有区间max的情况下可以代替线段树,比线段树快的不知道 哪里去了
具体看代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 100000
#define lowbit(x) ((x)&(-(x)))
int n,m,t,x,y;
long long w;
struct tagTreeArray
{
long long c[maxn],a[maxn];//前者存i*a[i],后者存差分
void upd(int x,long long k)//x...inf区间加一个数
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=x*k;
a[i]+=k;
}
}
long long query(int x)//查询1...x区间和
{
long long ans1=0,ans2=0;
for(int i=x;i>0;i-=lowbit(i))
{
ans1+=a[i];
ans2+=c[i];
}
return ans1*(x+1)-ans2;
}
void add(int l,int r,long long k)//[l,r]加一个数
{
upd(l,k);
upd(r+1,-k);
}
long long query(int l,int r)//查询l...r区间和
{
return query(r)-query(l-1);
}
}arr;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&x);
arr.add(i,i,x);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&t);
if(t==1)
{
scanf("%d%d%lld",&x,&y,&w);
arr.add(x,y,w);
}
if(t==2)
{
scanf("%d%d",&x,&y);
printf("%lld\n",arr.query(x,y));
}
}
}

浙公网安备 33010602011771号