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  }        

 

你可能感兴趣的:(OJ)