• 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  }        
  • 相关阅读:
    activiti流程跟踪图简单详解
    maven夹包引入的速度问题
    maven的pom.xml文件配置详解
    maven的简单使用
    Spring mail 邮件服务及其参数配置
    json格式的简单转换
    ajax的简单理解
    广告关闭按钮
    跨数据库调用
    如何完成DEDE CMS外部数据库调用|不同数据库调用数据
  • 原文地址:https://www.cnblogs.com/shihuajie/p/2972220.html
Copyright © 2020-2023  润新知