神奇的树状数组

树状数组的存储原理

转跳链接

(例题)ACM-HDOJ 1166

Problem Description

Input

Output

Sample Input

Sample Output

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
#define MAX 50005
int c[MAX],que[MAX];
int lowbit(int x)
{
return x&(-x);
}
void create(int n)
{
for(int i=1;i<=n;i++)
{
int s=lowbit(i);
for(int j=0;j<s;j++)
c[i]+=que[i-j];
}
}
int sum(int idx)
{
int sum=0;
while(idx>0)
{
int s=lowbit(idx);
sum+=c[idx];
idx-=s;
}
return sum;
}
void change(int i,int n,int x)
{
while(i<=n)
{
int s=lowbit(i);
c[i]+=x;
i+=s;
}
}
int main()
{
int t,j=1;
scanf("%d",&t);
while(t--)
{
int N;
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d",&que[i]);
memset(c,0,sizeof(c));
create(N);
cout<<"Case "<<j++<<":"<<endl;
while(1)
{
char ch[10];
int i,n,a,b;
scanf("%s",ch);
if(!strcmp(ch,"Add"))
{
scanf("%d%d",&i,&n);
change(i,N,n);
}
else if(!strcmp(ch,"Sub"))
{
scanf("%d%d",&i,&n);
change(i,N,-n);
}
else if(!strcmp(ch,"Query"))
{
scanf("%d%d",&a,&b);
int s=sum(b)-sum(a-1);
cout<<s<<endl;
}
else
break;
}
}
return 0;
}

模版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int a[maxn],tree[maxn];
int n;
void creat(){
for(int i=1;i<=n;i++){
for(int j=0;j<(i&(-i));j++) tree[i]+=a[i-j];
}
}
void change(int x,LL val){
while(x<=n) {
tree[x]+=val;
x+=x&(-x);
}
}
LL sum(int x){
LL res=0;
while (x){
res+=tree[x];
x-=x&(-x);
}
return res;
}
文章目录
  1. 1. 树状数组的存储原理
    1. 1.1. (例题)ACM-HDOJ 1166
      1. 1.1.1. 参考AC代码
      2. 1.1.2. 模版
|