树状数组
视频讲解
1.计算长度
int lowbit(int x)
{
return x & (-x);
}
2.计算前x项和
int query(int x)
{
int ret = 0;
while(x)
{
ret += c[x];
x = x -lowbit(x);
}
return ret;
}
实现在第x数上加上val
void add_x(int x,int val)
{
while(x <= n)
{
c[x] += val;
x = x +lowbit(x);
}
}
例题 :树状数组
题解:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 5e5+5;
ll C[N];
ll n,m;
ll x,y,k;
ll lowbit(ll x)
{
return x & (-x);
}
ll query(ll x)
{
ll res = 0;
while(x)
{
res +=C[x];
x = x-lowbit(x);
}
return res;
}
void add_x(ll x,ll val)
{
while(x <= n)
{
C[x] += val;
x = x + lowbit(x);
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int xx;
cin>>xx;
add_x(i,xx);
}
for(int i=1;i<=m;i++)
{
cin>>k>>x>>y;
if(k==1)
{
add_x(x,y);
}
if(k==2)
{
ll l,r;
l=query(x-1);
r=query(y);
cout<<r-l<<"\n";
}
}
}
例题:P3368 树状数组2 (差分+树状数组)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N =500005;
ll n,m,k;
ll c[N];
ll lowbit(ll x)
{
return x & (-x);
}
ll query(ll x)
{
ll res=0;
while(x)
{
res += c[x];
x -= lowbit(x);
}
return res;
}
void add_x(ll x,ll val)
{
while(x <= n)
{
c[x] += val;
x += lowbit(x);
}
}
int main()
{
cin>>n>>m;
ll now=0;;
ll a;
for(int i=1;i<=n;i++)
{
cin>>a;
add_x(i,a-now);//差分
now = a;//这里的now相当于上一个a
}
for(int i=1;i<=m;i++)
{
cin >> k ;
if(k==1)
{
ll x,y,z;
cin>>x>>y>>z;
add_x(x,z);//差分
add_x(y+1,-z);//差分
}
else if(k==2)
{
ll t;
cin>>t;
cout<<query(t)<<endl;
}
}
return 0;
}