树状数组
树状数组这个东西,因为它没有线段树的功能强大,所以在很多时候大家都不怎么用它。
但是树状数组有个好处就是它代码比较简单
嗯,,在洛谷上树状数组有专门的模板题
一个是单点修改,区间查询
嗯,直接附代码吧
#include<iostream>
#include<cstdio>
using namespace std;
int t[500010];
int n,m;
int lowbit(int x ){
return x&(-x);
}
void add(int x,int k ){
while(x<=n)
{
t[x]+=k;
x+=lowbit(x);
}
}
int query( int y ){
int sum=0;
while(y>0)
{
sum+=t[y];
y-=lowbit(y);
}
return sum;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
{ int a;
scanf("%d",&a);
add(i,a);
}
for(int i=1;i<=m;i++){
int z;
scanf("%d",&z);
if(z==1)
{
int x,k;
scanf("%d%d",&x,&k);
add(x,k);
}
if(z==2)
{
int x,y;
scanf("%d%d",&x,&y);
cout<<query(y)-query(x-1)<<endl;
}
}
return 0;
}
//以下是我的第一次写的代码
/*#include<iostream>
#include<cstdio>
#include<cstring> //树状数组单点修改,区间查询
using namespace std;
int a[500010];
int t[500010];
int n,m;
int lowbit(int x){ //lowbit数组实际上用了二进制
return x& (-x);
}
void add(int x,int k){ //给单点x加上k值
while(x<=n){
t[x]+=k; //给此后一直到n的数都加上k
//因为t是树状数组,以便下面求和
// 也就是不断更新父节点的值
x+=lowbit(x); //这里的x表示下标 ,所以是数组在逐渐向后
}
}
int sum(int x ){ //类似前缀和
int ans=0;
while(x!=0){
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int a;
scanf("%d",&a);
add(i,a);
}
for(int i=1;i<=m;i++){
int k,x,y;
scanf("%d%d%d",&k,&x,&y);
if(k==1)
add(x,y);
if(k==2)
printf("%d\n",sum(y)-sum(x-1));
}
return 0;
}*/
还有一种就是区间修改,单点查询
上代码
#include<iostream>
#include<cstdio>
using namespace std;
int a[500010];
int t[500010];
int n,m;
int lowbit(int x ){return x & ( -x );}
void add1 (int x ,int k){
while(x<=n){
t[x]+=k;
x+=lowbit(x);
}
}
void add2 (int x , int y , int k ){
while(x<=n){
t[x]+=k;
x+=lowbit(x);
}
y=y+1;
while(y<=n){
t[y]=t[y] - k;
y+=lowbit(y);
}
}
int query( int x ){
int sum=0;
while(x>0){
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
cin>>n>>m;
for(int i=1 ; i<=n ; i++ ){
scanf("%d",&a[i]);
add1(i,a[i]-a[i-1]);
}
for(int i=1;i<=m;i++){
int z;
scanf("%d",&z);
if(z==1)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
add2 (x , y , k );
}
if(z==2)
{
int x;
scanf("%d",&x);
cout<<query(x)<<endl;
}
}
}
//第一次
/*#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int t[500010];
int a[500010];
int lowbit(int x){
return x & (-x);
}
void add(int x,int k){
while(x<=n){
t[x]+=k;
x+=lowbit(x);
}
}
int update(int l,int r,int k){
add(l,k);
add(r+1,-k);
}
int query(int x){
int ans=0;
while(x>0){
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
int now=0;
int a;
for(int i=1;i<=n;i++){
scanf("%d",&a);
add(i,a-now);
now=a;
}
for(int i=1;i<=m;i++){
int flag;
scanf("%d",&flag);
if(flag==1){
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
update(x,y,k);
}
if(flag==2){
int x;
scanf("%d",&x);
printf("%d\n",query(x));
}
}
return 0;
} */

浙公网安备 33010602011771号