本蒟蒻是一个萌新,希望支持。
见本蒟蒻的博客
【模板】树状数组 2(洛谷)
树状数组 2 :区间修改,单点查询(Liuser’s OJ)
如题,已知一个数列,你需要进行下面两种操作:
第一行包含两个整数 N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含 N 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 M 行每行包含 2 或 4个整数,表示一个操作,具体如下:
1 x y k
2 x
输出包含若干行整数,即为所有操作 2 的结果。
5 5
1 5 4 2 3
1 2 4 2
2 3
1 1 5 -1
1 3 5 7
2 4
6
10
#include
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)
#include
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:单点修改,区间查询(Liuser’s OJ)
#include
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:区间修改,区间查询(Liuser’s OJ)
#include
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;
}