树状数组的一些基本题型吧
之前说过,树状数组能做的东西线段树都能做
代码这么简单的树状数组能不能做线段树经常要做的改点(段)求段(点)呢?
废话,这么简单的东西答案当然是能啦
1、
改点求段
代码:
#include <cstdio>
#include <cstring>
using namespace std;
int c[100010],l[100010],n;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int y)
{
while (x<=100000)
{
c[x]+=y;
x+=lowbit(x);
}
}
int getsum(int x)
{
int s=0;
while (x>=1)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int n,x,y,z,u,m;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&u);
add(i,u);
}
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&u);
if (u==1)
{
scanf("%d%d",&x,&z);
add(x,z);
}
else
{
scanf("%d%d",&x,&y);
printf("%d\n",getsum(y)-getsum(x-1));
//[x~y]=[1~Y]-[1~X-1];
}
}
return 0;
}
2、
改段求点
(codevs1081 )
#include <cstdio>
#include <cstring>
using namespace std;
int c[100010],l[100010],n;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int y)
{
while (x<=100000)
{
c[x]+=y;
x+=lowbit(x);
}
}
int getsum(int x)
{
int s=0;
while (x>=1)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int n,x,y,z,u,m;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&u);
add(i,u);//[i~n]都加z
add(i+1,-u);//只更改i这个点,所以[i+1,n]以后的点要还原
}
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&u);
if (u==1)
{
scanf("%d%d%d",&x,&y,&z);
add(x,z);//[x~n]的点都加z
add(y+1,-z);//因为只是更改[x~y]的点,所以[y+1~n]要还原
}
else
{
scanf("%d",&x);
printf("%d\n",getsum(x));
}
}
return 0;
}
3、
改段求段
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200009
using namespace std;
int n,m;long long c[2][N];
int lowbit(int x)
{
return x&-x;
}
void add(int x,long long y,int opp)
{
while(x<=n)
{
c[opp][x]+=y;
x+=lowbit(x);
}
}
long long getsum(int x,int opp)
{
long long s=0;
while(x>=1)
{
s+=c[opp][x];
x-=lowbit(x);
}
return s;
}
long long ans(int x)//ASK:ans=X.sum(k)*k+Y.sum(k)
{
return (x+1)*getsum(x,0)+getsum(x,1);
}
int main()
{
int i,j,k,x,y,opp;
long long z;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&x);
add(i,x,0),add(i+1,-x,0);
add(i,-x*i,1),add(i+1,x*(i+1),1);
}
int m;scanf("%d",&m);
while(m--)
{
scanf("%d%d%d",&opp,&x,&y);
if(opp==1)
{
scanf("%lld",&z);
/*
CHANGE:
X[L]+=val,X[R+1]-=val
Y[L]+=-val*(L-1),Y[R+1]+=val*R;
*/
add(x,z,0),add(y+1,-z,0);
add(x,-x*z,1),add(y+1,(y+1)*z,1);
}
else printf("%lld\n",ans(y)-ans(x-1));
}
}