1 #include<stdio.h> 2 int m,n,tree[1000010]; 3 void update(int index,int inc)//注意插线问点与插点问线的区别 4 { 5 while(index>0){ 6 tree[index]+=inc; 7 index-=index&(-index); 8 } 9 } 10 int sum(int index) 11 { 12 int sum=0; 13 while(index<=n){ 14 sum+=tree[index]; 15 index+=index&(-index); 16 } 17 return sum; 18 } 19 int main() 20 { 21 int from,to,inc,query; 22 char cmd[7]; 23 scanf("%d%d",&m,&n); 24 while(m--){ 25 scanf("%s",cmd); 26 if(cmd[0]=='A'){ 27 scanf("%d%d%d",&from,&to,&inc); 28 update(from-1,-inc); 29 update(to,inc); 30 }else{ 31 scanf("%d",&query); 32 printf("%d\n",sum(query)); 33 } 34 } 35 return 0; 36 }
上面是用树状数组写的,一直能AC,重新复习了一下树状数组,以前只用了它的插点问线的功能,今天用了一下它的插线问点的功能,感觉还可以吧,对于线段树与树状数组的利弊,感觉树状数组能完成的功能,线段树都能完成,但反过来就不一定了,还是线段树比较强大,但是有时树状数组在内存与运行效率上却很占优势,比如本题,线段树方法:时间:1828 内存:35384 而树状数组方法:时间:892 内存:4132,果然有区别,先告一段落吧!
今天看了一下士兵杀敌(四)竟然发现还没过,感觉用树状数组能过,用线段树应该也能过啊,用以前提交的代码发现有时AC,有时TL,是用线段树写的,贴上代码:
1 2 #include<stdio.h> 3 #define N 1000010 4 struct node{ 5 int l,r; 6 int inc; 7 }tree[3*N]; 8 void build(int l,int r,int i) 9 { 10 tree[i].l=l; 11 tree[i].r=r; 12 if(l<r){ 13 int mid=(l+r)>>1; 14 build(l,mid,i<<1); 15 build(mid+1,r,(i<<1)+1); 16 } 17 } 18 void add(int l,int r,int inc,int i) 19 { 20 if(l==tree[i].l&&tree[i].r==r){//要是l为0的话就不能这样写了,否则RE,死循环 21 tree[i].inc+=inc;//加的时候单单加到本段,不往下压 22 return; 23 } 24 int mid=(tree[i].l+tree[i].r)>>1; 25 if(r<=mid) add(l,r,inc,i<<1); 26 else if(l>mid) add(l,r,inc,(i<<1)+1); 27 else{ 28 add(l,mid,inc,i<<1); 29 add(mid+1,r,inc,(i<<1)+1); 30 } 31 } 32 inline int query(int k,int i) 33 { 34 if(tree[i].l<tree[i].r){//查询的时候父辈的inc值往下压,直到压到叶子节点为止 35 if(tree[i].inc){ 36 tree[i<<1].inc+=tree[i].inc; 37 tree[(i<<1)+1].inc+=tree[i].inc; 38 tree[i].inc=0;//记得清零 39 } 40 int mid=(tree[i].l+tree[i].r)>>1; 41 if(k<=mid) return query(k,i<<1); 42 else return query(k,(i<<1)+1); 43 } 44 return tree[i].inc;//返回此叶子节点的值,也即是结果 45 } 46 int main() 47 { 48 int a,b,inc,n,q; 49 char cmd[6]; 50 scanf("%d%d",&q,&n); 51 build(1,n,1); 52 while(q--){ 53 scanf("%s",cmd); 54 if(*cmd=='A'){ 55 scanf("%d%d%d",&a,&b,&inc); 56 if(!a) a++;//真像讨论区有人说的那样本题测试数据有Bug,a可能为0,坑爹啊! 57 add(a,b,inc,1); 58 }else{ 59 scanf("%d",&a); 60 printf("%d\n",query(a,1)); 61 } 62 } 63 return 0; 64 }