树状数组的三种操作

  • Post author:
  • Post category:其他


直接贴代码

一、改点求段


namespace BIT

{

#define N 100000

#define lowbit(a) ((a)&(-a))

int c[N],num;

void init(int n){num=n;}

inline void add(int x,int a)

{

int xx=x;

while(xx<=num)c[xx]+=a,xx+=lowbit(xx);

}

inline int sum(int x)

{

int sum_=0,xx=x;

while(xx)sum_+=c[xx],xx-=lowbit(xx);

return sum_;

}

inline int sum(int l,int r)

{

return sum(r)-sum(l-1);

}

#undef N

#undef lowbit

};

二、改段求点


namespace BIT

{

#define N 100000

#define lowbit(a) ((a)&(-a))

int c[N],b[N],num;

void init(int n){num=n;}

inline void add(int l,int r,int x)

{

for(int i=l-1;i;i-=lowbit(i))b[i]-=x;

for(int i=r;i;i-=lowbit(i))b[i]+=x;

}

inline int sum(int x)

{

int s=0;

for(int i=x;i<=num;i+=lowbit(i))s+=b[i];

return s;

}

#undef N

#undef lowbit

};

三、改段求段`

namespace BIT

{

#define lowbit(x) ((x)&(-x))

#define cl(x) memset(x,0,sizeof(x))

int b[100010],c[100010],maxn;

void init(int n){maxn=n;cl(b);cl(c);}

inline void add(int l,int r,int x)

{

for(int i=r;i;i-=lowbit(i))b[i]+=x;

for(int i=r;i<=maxn;i+=lowbit(i))c[i]+=x*r;

if(l>1)

{

for(int i=l-1;i;i-=lowbit(i))b[i]-=x;

for(int i=l-1;i<=maxn;i+=lowbit(i))c[i]-=x*(l-1);

}

}

inline int sum(int x)

{

int s=0;

if(x>1)

{

for(int i=x;i<=maxn;i+=lowbit(i))s+=b[i];

s*=x;

for(int i=x-1;i;i-=lowbit(i))s+=c[i];

}

return s;

}

inline int sum(int l,int r)

{

return sum(r)-sum(l-1);

}

#undef lowbit

#undef cl

};`



版权声明:本文为Vectorxj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。