树状数组

Posted jd1412

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组相关的知识,希望对你有一定的参考价值。

树状数组

lowbit : 求最低位的 (1) 以及后面的 (0) 所组成的十进制数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;

const ll maxn=5e5+10;
ll n,m;

struct node
{
	ll tree[maxn];
	
	ll lowbit(const ll x)
	{
		return x & -x;
	}
	void upd(ll p,ll w)
	{
		do tree[p]+=w;
		while((p+=lowbit(p))<=n);
	}
	ll qry(ll p)
	{
		ll ret=0;
		
		do ret+=tree[p];
		while((p-=lowbit(p))!=0);
		
		return ret;
	}
}bit;

int main(void)
{
	scanf("%lld%lld",&n,&m);
	
	ll w,x,o;
	
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&x);
		bit.upd(i,x);
	}
	
	for(int i=1;i<=m;i++)
	{
		scanf("%lld",&o);
		
		if(o==1)
		{
			scanf("%lld%lld",&w,&x);
			bit.upd(w,x);
		}
		else
		{
			scanf("%lld%lld",&w,&x);
			printf("%lld
",bit.qry(x)-bit.qry(w-1));
		}
	}
	
	return 0;
}

求逆序对:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;

const ll maxn=5e5+10;
ll n,m,sum;
ll a[maxn],b[maxn],c[maxn];

inline ll lowbit(ll x)
{
	return x & (-x);
}
inline void upd(ll x,ll w)
{
	for( ;x<=n;x+=lowbit(x)) c[x]+=w;
}
inline ll qry(ll x)
{
	ll ret=0;
	for( ;x;x-=lowbit(x)) ret+=c[x];
	return ret;
}
inline void init_hash()
{
	scanf("%lld",&n);
	
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
	}
	memcpy(b+1,a+1,n*sizeof(ll));
	sort(b+1,b+n+1);
	ll *bg=b+1;
	ll *ed=unique(b+1,b+n+1);
	for(int i=1;i<=n;i++)
	{
		a[i]=lower_bound(bg,ed,a[i])-b;
	}
}
inline void solve()
{
	for(int i=1;i<=n;i++) upd(i,1);
	for(int i=1;i<=n;i++)
	{
		sum+=qry(a[i]-1);
		upd(a[i],-1);
	}
	printf("%lld
",sum);
}

int main(void)
{
	init_hash();
	solve();
	return 0;
}

以上是关于树状数组的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之树状数组从零认识树状数组

树状数组和线段树有啥区别?

树状数组

树状数组

树状数组

如何利用树状数组修改一个区间?