樹狀數組模板
樹狀數組的應用:
- 單點更新-區間查詢
- 區間更新-單點查詢
- 區間更新-區間查詢
一、單點更新-區間查詢
代碼:
#include<cstdio>
#include<cstring>
int sum[2000000+2];
int n,m;
inline int lowerbit(int x)
{
return x&-x;
//return x-(x&(x-1));
}
void UpDate(int x,int y)
{
while(x<=n)
{
sum[x]+=y;
x+=lowerbit(x);
}
}
int query(int x)
{
int ans=0;
while(x>0)
{
ans+=sum[x];
x-=lowerbit(x);
}
return ans;
}
int main()
{
memset(sum,0,sizeof(sum));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int t;
scanf("%d",&t);
UpDate(i,t);
}
char str[10];
int l,r;
while(m--)
{
scanf("%s%d%d",&str,&l,&r);
if(str[0]=='Q')
{
printf("%d\n",query(r)-query(l-1));
}
else
{
UpDate(l,r);
}
}
return 0;
}
二、區間更新-單點查詢
題目鏈接:HDU1556 Color the ball
代碼:
//差分數組的理解
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=100010;
int c[MAXN];
int n;
int lowbit(int x)
{
return x&(-x);
}
void addd(int i,int val)
{
while(i<=n)
{
c[i]+=val;
i+=lowbit(i);
}
}
int sum(int i)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main()
{
int l,r;
while(scanf("%d",&n),n)
{
memset(c,0,sizeof(c));
for(int i=0;i<n;i++)
{
scanf("%d%d",&l,&r);
add(l,1);
add(r+1,-1);
}
for(int i=1;i<n;i++)
printf("%d ",sum(i));
printf("%d\n",sum(n));
}
return 0;
}
三、區間更新-區間查詢
題目鏈接:POJ 3468 A Simple Problem with Integers
代碼:
#include<cstdio>
#include<cstring>
#define ll long long int
#define lowerbit(x) (x&-x)
const int maxn=100000+5;
int n,q;
ll sum[maxn];//原始數組前綴和
ll c1[maxn],c2[maxn];
void add(int i,int x)
{
int pos=i;
while(pos<=n)
{
c1[pos]+=x;
c2[pos]+=i*x;
pos+=lowerbit(pos);
}
}
ll query(ll x)
{
ll ans=0;
int i=x;
while(i>0)
{
ans+=(x+1)*c1[i]-c2[i];
i-=lowerbit(i);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&q);
memset(sum,0,sizeof(sum));
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=1;i<=n;i++)
{
ll t;
scanf("%lld",&t);
sum[i]=sum[i-1]+t;
}
char str[4];
int l,r,p;
for(int i=0;i<q;i++)
{
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d%d",&l,&r);
printf("%lld\n",sum[r]-sum[l-1]+query(r)-query(l-1));
}
else
{
scanf("%d%d%d",&l,&r,&p);
add(l,p);
p=-p;
add(r+1,p);
}
}
return 0;
}