树状数组例题

本蒟蒻是一个萌新,希望支持。

单点修改,区间查询

见本蒟蒻的博客

树状数组 2 :区间修改,单点查询

【模板】树状数组 2(洛谷)
树状数组 2 :区间修改,单点查询(Liuser’s OJ)

题目描述

如题,已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数数加上 x;
  2. 求出某一个数的值。

输入格式

第一行包含两个整数 N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含 N 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 M 行每行包含 2 或 4个整数,表示一个操作,具体如下:

  1. 含义:将区间 [x,y] 内每个数加上 k;
1 x y k
  1. 含义:输出第 xxx 个数的值。
2 x

输出格式

输出包含若干行整数,即为所有操作 2 的结果。

样例

样例1输入
5 5
1 5 4 2 3
1 2 4 2
2 3
1 1 5 -1
1 3 5 7
2 4
样例1输出
6
10

AC代码+注释

#include<bits/stdc++.h>
using namespace std;

long long a[1000005],BIT[1000005],n,q,s=0,t,l,r,z;

long long Lowbit(long long x)
{
 return x&-x;
}

long long Sum(long long x)
{
 long long ans=0;
 for(long long i=x;i;i-=Lowbit(i))
 {
  ans+=BIT[i];
 }
 return ans;
}

void Add(long long x,long long y)
{
 while(x<=n)
 {
  BIT[x]+=y;
  x+=Lowbit(x);
 }
}

int main()
{
 scanf("%lld%lld",&n,&q);
 for(long long i=1;i<=n;i++)
 {
  scanf("%lld",&a[i]);
  Add(i,a[i]-s);
  s=a[i];
 }
 for(long long i=0;i<q;i++)
 {
  scanf("%lld",&t);
  if(t==1)
  {
   scanf("%lld%lld%lld",&l,&r,&z);
   Add(l,z);
   Add(r+1,-z);
  }
  else
  {
   scanf("%lld",&l);
   printf("%lld\n",Sum(l));
  }
 }
 return 0;
}

区间修改,区间查询

树状数组 3 :区间修改,区间查询(Liuser’s OJ)

AC代码+注释

#include<bits/stdc++.h>
using namespace std;

long long n,q,a[1000005],BIT1[1000005],BIT2[1000005],t,l,r,x;

long long Lowbit(long long x)
{
 return x&-x;
}

void Update(long long x,long long y)
{
 for(long long i=x;i<=n;i+=Lowbit(i))
 {
  BIT1[i]+=y;
  BIT2[i]+=(long long)(x-1)*y;
 }
}

long long Sum(long long x)
{
 long long ans=0;
 for(long long i=x;i;i-=Lowbit(i))
 {
  ans+=BIT1[i]*x-BIT2[i];
 }
 return ans;
}

int main()
{
 scanf("%lld%lld",&n,&q);
 for(long long i=1;i<=n;i++)
 {
  scanf("%lld",&a[i]);
  Update(i,a[i]-a[i-1]);
 }
 for(long long i=1;i<=q;i++)
 {
  scanf("%lld%lld%lld",&t,&l,&r);
  if(t==1)
  {
   scanf("%lld",&x);
   Update(l,x);
   Update(r+1,-x);
  }
  else
  {
   printf("%lld\n",Sum(r)-Sum(l-1));
  }
 }
 return 0;
}

二维树状数组 1:单点修改,区间查询

二维树状数组 1:单点修改,区间查询(Liuser’s OJ)

AC代码+注释

#include<bits/stdc++.h>
using namespace std;

long long BIT[10005][10005],n,m,flag,a,b,c,d;

long long Lowbit(long long x)
{
 return x&(-x);
}

void Update(long long x,long long y,long long z)
{
 for(long long i=x;i<=n;i+=Lowbit(i))
 {
  for(long long j=y;j<=m;j+=Lowbit(j))
  {
   BIT[i][j]+=z;
  }
 }
}

long long Sum(long long x,long long y)
{
 long long ans=0;
 for(long long i=x;i>0;i-=Lowbit(i))
 {
  for(long long j=y;j>0;j-=Lowbit(j))
  {
   ans+=BIT[i][j];
  }
 }
 return ans;
}

int main()
{
 scanf("%lld%lld",&n,&m);
 while(scanf("%lld",&flag)!=EOF)
 {
  scanf("%lld%lld%lld",&a,&b,&c);
  if(flag==1)
  {
   Update(a,b,c);
  }
  else
  {
   scanf("%lld",&d);
   printf("%lld\n",Sum(c,d)+Sum(a-1,b-1)-Sum(a-1,d)-Sum(c,b-1));
  }
 }
 return 0;
}

二维树状数组 3:区间修改,区间查询

二维树状数组 3:区间修改,区间查询(Liuser’s OJ)

#include<bits/stdc++.h>
using namespace std;

long long s[2050][2050],ss[2050][2050],sss[2050][2050],ssss[2050][2050],n,m,flag,a,b,c,d,e;

long long Lowbit(long long x)
{
 return x&-x;
}

void Update(long long x,long long y,long long z)
{
 for(long long i=x;i<=n;i+=Lowbit(i))
 {
  for(long long j=y;j<=n;j+=Lowbit(j))
  {
   s[i][j]+=z;
   ss[i][j]+=x*z;
   sss[i][j]+=y*z;
   ssss[i][j]+=x*y*z;
  }
 }
 return ;
}

long long Sum(long long x,long long y)
{
 long long sum=0;
 for(long long i=x;i;i-=Lowbit(i))
 {
  for(long long j=y;j;j-=Lowbit(j))
  {
   sum+=(x+1)*(y+1)*s[i][j]-(y+1)*ss[i][j]-(x+1)*sss[i][j]+ssss[i][j];
  }
 }
 return sum;
}

int main()
{
 scanf("%lld%lld",&n,&m);
 memset(s,0,sizeof(s));
 memset(ss,0,sizeof(ss));
 memset(sss,0,sizeof(sss));
 memset(ssss,0,sizeof(ssss));
 while(scanf("%lld",&flag)!=EOF)
 {
  scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
  if(flag==1)
  {
   scanf("%lld",&e);
   Update(a,b,e);
   Update(c+1,b,-e);
   Update(a,d+1,-e);
   Update(c+1,d+1,e);
  }
  else
  {
   printf("%lld\n",Sum(c,d)-Sum(a-1,d)-Sum(c,b-1)+Sum(a-1,b-1));
  }
 }
 return 0;
}

猜你喜欢

转载自blog.csdn.net/cqbzybc20220707/article/details/107621447