摘取几个树状数组相关的题。
1·区间更新,单点求和。
链接:点击打开链接
hdu1556
#include<stdio.h>
#include<cstring>
int c[100005];
int a,b,n;
int lowbit(int t)
{
return t&(-t);
}
void add(int x,int y)
{
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=y;
}
int getsum(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main()
{
while(scanf("%d",&n)&&n)
{
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
add(a,1);
add(b+1,-1);
}
for(int i=1;i<=n;i++)
{
if(i==1)
printf("%d",getsum(i));
else
printf(" %d",getsum(i));
}
printf("\n");
}
return 0;
}
2·区间更新,区间求和
链接:点击打开链接
#include<stdio.h>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<math.h>
#include<stdlib.h>
#include<malloc.h>
using namespace std;
long long m[1000005],c1[100005],c2[100005];
long long a,b,d,n,q;
long long lowbit(long long t)
{
return t&(-t);
}
void add(long long *c,long long x,long long y)
{
for(long long i=x;i<=n;i+=lowbit(i))
c[i]+=y;
}
long long getsum(long long *c,long long x)
{
long long ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main()
{
while(scanf("%lld%lld",&n,&q)!=EOF)
{
char s;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
memset(m,0,sizeof(m));
for(int i=1;i<=n;i++)
{
scanf("%lld",&m[i]);
add(c1,i,m[i]-m[i-1]);
add(c2,i,(i-1)*(m[i]-m[i-1]));
}
getchar();
for(int i=0;i<q;i++)
{
s=getchar();
if(s=='C')
{
scanf("%lld%lld%lld",&a,&b,&d);
add(c1,a,d);add(c1,b+1,-d);
add(c2,a,d*(a-1));add(c2,b+1,-d*b);
}
if(s=='Q')
{
long long sum1,sum2;
scanf("%lld%lld",&a,&b);
sum1=(a-1)*getsum(c1,a-1)-getsum(c2,a-1);
sum2=b*getsum(c1,b)-getsum(c2,b);
printf("%lld\n",sum2-sum1);
}
getchar();
}
}
return 0;
}
3· 树状数组求逆序数:
链接:点击打开链接
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
struct f{
long long a,b;
}arr[500005];
int n,c[500005],num[500005];
bool cmp(struct f a,struct f b)
{
return a.a<b.a;
}
int lowbit(int t)
{
return t&(-t);
}
void add(long long x,int y)
{
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=y;
}
int getsum(long long x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
int main()
{
while(scanf("%d",&n)&&n)
{
memset(c,0,sizeof(c));
memset(num,0,sizeof(num));
memset(arr,0,sizeof(arr));
for(int i=1;i<=n;i++)
{
scanf("%lld",&arr[i].a);
arr[i].b=i;
}
sort(arr+1,arr+1+n,cmp);
for(int i=1;i<=n;i++)
num[arr[i].b]=i;
long long sum=0;
for(int i=1;i<=n;i++)
{
add(num[i],1);
sum+=i-getsum(num[i]);
}
printf("%lld\n",sum);
}
return 0;
}