JieJie的学习记录--树状数组+线段树(模板)

线段树,树状树组的基本操作(模板)

树状数组:

1.单点修改,区间查询
2.区间修改,单点查询
3.区间修改,区间查询

零.基础:

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

一.单点修改,区间查询

1.T[ ]内的元素

  for(int i=1;i<=n;i++) //直接将a[ ]存入T[ ]年内进行维护
	{
		cin>>a[i];
		add(i,a[i]);
   }

2.(存储T [ ])/(修改)

void add(int i,int x)
{
	while(i<=n)
	{
		T[i]+=k;
		i+=lowbit(i);
	}
}

3.询问

int getsum(int i)
{
	int res=0;
	while(i)
    {
    	res+=T[i];
		i-=lowbit(i); 
	}
   return res;
}

二.区间修改,单点查询

1.T[ ]内的元素

for(int i=1;i<=n;i++)
{
  cin>>a[i];
  add(i,a[i]-a[i-1);//这里用其差分来存进
}

2.区间修改

int l,r,k; //需要修改的区间[l,r],以及修改的大小k
cin>>l>>r>>k;
add(l,k);
add(r+1,-k);

3.询问:如上。

三.区间修改,区间查询

1.t1[ ],t2[ ]的元素(需要用2个数组来维护),如上(t2用其差分存储)
2.存储/修改:

void add(int i,int k)
{
int x=i;
  while(i<=n)
  {
    t1[i]+=k;
    t2[i]+=(x-1)*k;
    i+=lowbit(i)
  }
}

3.查询

int getsum(int i)
{
int res=0;
int x=i;
while(i)
{
res+=s1[i]*x-s2[i];
i-=lowbit(i);
}
return res;
}

//其中 
int l,r;
cin>>l>>r;
int ans;
ans=getsum(r)-getsum(l-1);

线段树

1.建树
2.单点修改
3.区间查询,区间修改

0.懒惰标记:

void push_down(int i,int l,int r)
{
if(lz[i])
{
int mid=(l+r)>>1;
  lz[i*2]+=lz[i];
  lz[i*2+1]+=lz[i];
  T[i*2]+=(mid-l+1)*lz[i];
  T[i*2+1]+=(r-mid)*lz[i];
  lz[i]=0;
}
}

1.建树:

void built(int i,int l,int r)
{
  if(l==r)
  {cin>>T[i];
  return;
  }
  int mid=(l+r)>>1;
  built(i*2,l,mid);
  built(i*2+1,mid+1,r);
  T[i]=T[i*2]+T[i*2+1];
}

2.单点修改

void updata(int pos,int i,int k,int l,int r)
{
   if(l==r)
   {T[i]+=k;
   return;
   }
   int mid=(l+r)>>1;
   if(pos<=mid)
     updata(pos,i*2,k,l,mid);
   else
     updata(pos,i*2+1,mid+1,r);
}

3.区间修改,区间查询:

void updata_arrange(int i,int k,int l,int r,int L,int R)//区间修改
{
   if(l>=L && r<=R)
   {
     T[i]+=k*(R-L+1);
     lz[i]+=k;
     return;
   }
   push_down(i,l,r);
   int mid=(l+r)>>1;
   if(mid>=L)
     updata_arange(i*2,k,l,mid,L,R);
    if(mid<R)
      updata_arange(i*2+1,k,mid+1,r,L,R);
     T[i]=T[i*2]+T[i*2+1];
}

int q_arrange(int i,int l,int r,int L,int R)
{
int sum=0;
   if(l>=L && r<=R)
   {
   sum+=T[i];
   return sum;
   }
   push_down(i,l,r);
   int mid=(l+r)>>1;
   if(mid>=L)
   {
   sum+=q_arrange(i*2,l,mid,L,R);
   }
   if(mid<R)
     sum+=q_arrange(i*2+1,mid+1,r,L,R);
    return sum;
}

Con:简而精,欲知其所以然者,另觅高就

你可能感兴趣的:(JieJie的学习记录,学习,c++,算法)