zoukankan      html  css  js  c++  java
  • POJ 3468 线段树裸题

      这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解。

      然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了ACdreamer的模板,在此基础上自己用宏定义来精简了一下代码:

     1 #include<cstdio>
     2 typedef long long LL;
     3 #define root  int rt, int l, int r
     4 #define lson  rt*2, l, mid
     5 #define rson  rt*2+1, mid+1, r
     6 #define makemid  int mid= (l+r)>>1
     7 int a,b;
     8 LL c;
     9 
    10 struct tree {
    11     LL add,sum;
    12 } s[400003];
    13 
    14 void build(root) {
    15     s[rt].add= 0;
    16     if(l==r){
    17         scanf("%lld",&s[rt].sum);
    18         return ;
    19     }
    20     makemid ;
    21     build(lson);
    22     build(rson);
    23     s[rt].sum= s[rt*2].sum+s[rt*2+1].sum;
    24 }
    25 
    26 inline void pushdown(int rt, int len) {
    27     int ls= rt*2, rs= ls+1;
    28     const LL &c= s[rt].add;
    29     s[ls].add += c;
    30     s[rs].add += c;
    31     s[ls].sum += c*(len-len/2);
    32     s[rs].sum += c*(len/2);
    33     s[rt].add= 0;
    34 }
    35 
    36 void update(root) {
    37     if(a<=l && r<=b){
    38         s[rt].add+= c;
    39         s[rt].sum+= c*(r-l+1);
    40         return ;
    41     }
    42     if(s[rt].add)    pushdown(rt,r-l+1);
    43     makemid ;
    44     if(a<=mid)    update(lson);
    45     if(b>mid)    update(rson);
    46     s[rt].sum= s[rt*2].sum+s[rt*2+1].sum;
    47 }
    48 
    49 LL query(root) {
    50     if(a<=l && r<=b)    return s[rt].sum;
    51     if(s[rt].add)    pushdown(rt,r-l+1);
    52     makemid ;
    53     LL res= 0;
    54     if(a<=mid)    res+= query(lson);
    55     if(b>mid)    res+= query(rson);
    56     return res;
    57 }
    58 
    59 int main(){
    60     int n,q;
    61     while(~scanf("%d%d",&n,&q)){
    62         build(1,1,n);
    63         while(q--){
    64             getchar();
    65             if(getchar()=='Q'){
    66                 scanf("%d%d",&a,&b);
    67                 printf("%lld
    ",query(1,1,n));
    68             }
    69             else {
    70                 scanf("%d%d%lld",&a,&b,&c);
    71                 update(1,1,n);
    72             }
    73         }
    74     }
    75     return 0;
    76 }

      原样的代码是:

     1 #include<cstdio>
     2 typedef long long LL;
     3 LL c;
     4 int a,b;
     5 
     6 struct tree{
     7     LL add,sum;
     8 } s[400003];
     9 
    10 void build(int rt, int l, int r){
    11     s[rt].add= 0;
    12     if(l==r){
    13         scanf("%lld",&s[rt].sum);
    14         return ;
    15     }
    16     int mid= (l+r)>>1;
    17     build(rt*2,l,mid);
    18     build(rt*2+1,mid+1,r);
    19     s[rt].sum= s[rt*2].sum+s[rt*2+1].sum;
    20 }
    21 
    22 inline void pushdown(int rt, int len){
    23     if(s[rt].add){
    24         int ls= rt*2, rs= ls+1;
    25         s[ls].add += s[rt].add;
    26         s[rs].add += s[rt].add;
    27         s[ls].sum += s[rt].add*(len-len/2);
    28         s[rs].sum += s[rt].add*(len/2);
    29         s[rt].add= 0;
    30     }
    31 }
    32 
    33 void update(int rt, int l, int r){
    34     if(a<=l && r<=b){
    35         s[rt].add+= c;
    36         s[rt].sum+= c*(r-l+1);
    37         return ;
    38     }
    39     pushdown(rt,r-l+1);
    40     int mid= (l+r)>>1;
    41     if(a<=mid)    update(rt*2,l,mid);
    42     if(b>mid)    update(rt*2+1,mid+1,r);
    43     s[rt].sum= s[rt*2].sum+s[rt*2+1].sum;
    44 }
    45 
    46 LL query(int rt, int l, int r){
    47     if(a<=l && r<=b)    return s[rt].sum;
    48     pushdown(rt,r-l+1);
    49     int mid= (l+r)>>1;
    50     LL res= 0;
    51     if(a<=mid)    res+= query(rt*2,l,mid);
    52     if(b>mid)    res+= query(rt*2+1,mid+1,r);
    53     return res;
    54 }
    55 
    56 int main(){
    57     int n,q;
    58     while(~scanf("%d%d",&n,&q)){
    59         build(1,1,n);
    60         while(q--){
    61             getchar();
    62             if(getchar()=='Q'){
    63                 scanf("%d%d",&a,&b);
    64                 printf("%lld
    ",query(1,1,n));
    65             }
    66             else {
    67                 scanf("%d%d%lld",&a,&b,&c);
    68                 update(1,1,n);
    69             }
    70         }
    71     }
    72     return 0;
    73 }
    View Code

      线段树,不断进取中~~

  • 相关阅读:
    hdu2302(枚举,大数取模)
    hdu2108(判断凸多边形)
    Codeforces Round #324 (Div. 2) C (二分)
    hdu1798(圆的位置关系)
    hdu1722(gcd)
    alias命令(使用命令别名)
    关于Linux环境变量
    poj1988(并查集)
    Linux基本命令
    Pandas数据规整
  • 原文地址:https://www.cnblogs.com/Newdawn/p/4197240.html
Copyright © 2011-2022 走看看