NYOJ 123 士兵杀敌(四)

 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  }        

 

posted on 2013-03-20 22:33  小花熊  阅读(196)  评论(0编辑  收藏  举报

导航