数据结构好伤啊,今天碰到一个map竟然自己没有看明白,我会找时间好好写一篇map和vector的博客。
明白他的存放方式。我先给一张网上找的图片(引用自https://images0.cnblogs.com/blog/402333/201303/02130035-8a70c86ecf024c049fa956184de467ab.png)。
不过这张图片比较抽象,也可以观察刘汝佳的训练指南P195,不过最好理解的方法还是看百度的解释(出乎意料的简单啊)
百度:
令这棵树的结点编号为C1,C2...Cn。令每个结点的值为这棵树的值的总和,那么容易发现:
C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
...
C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16
我们不难发现当lowbit(i)为几时我们就把a[i]储存前几位的和,这样就会产生对应的add和sum(add是对a[i]进行添加,sum是对a[i](包括a[i])进行求和)
sum:先拿a[6]来讲由于a[6]已经储存了a[5]所以我们便不需要再加a[5]了,而神奇的是恰巧loebit(6)为2,这样就可以避开a[5]了,如果想理解的更清楚请学习刘汝佳的训练指南。
add:不仅要修改本身还要修改后面带有a[i]的,同样的lowbit(i)也可以解决这个问题。
总之一句话,好神奇!
这里介绍一道入门题方便理解HDU1518,后附AC代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define N 50050 6 int n; 7 int a[N],c[N]; 8 int lowbit( int x ){ 9 return (x&-x); 10 } 11 void add(int i,int w){ 12 while(i<=n){ 13 c[i]+=w; 14 i=i+lowbit(i); 15 } 16 } 17 int sum(int i){ 18 int sum=0; 19 while(i>0){ 20 sum+=c[i]; 21 i=i-lowbit(i); 22 } 23 return sum; 24 } 25 int main() 26 { 27 int t,w,u,v; 28 int cas=0; 29 char st[100]; 30 scanf("%d",&t); 31 while(t--){ 32 scanf("%d",&n); 33 for(int i=0;i<=n;i++) 34 a[i]=c[i]=0; 35 for(int i=1;i<=n;i++){ 36 scanf("%d",&w); 37 add(i,w); 38 } 39 printf("Case %d: ",++cas); 40 while(scanf("%s",st),strcmp(st,"End")!=0){ 41 scanf("%d%d",&u,&v); 42 if(strcmp(st,"Query")==0){ 43 printf("%d ",sum(v)-sum(u-1)); 44 }else if(strcmp(st,"Add")==0){ 45 add(u,v); 46 }else if(strcmp(st,"Sub")==0){ 47 add(u,-v);//化减法为负值; 48 } 49 50 51 } 52 } 53 }