zoukankan      html  css  js  c++  java
  • 【成端更新线段树模板】POJ3468-A Simple Problem with Integers

    http://poj.org/problem?id=3468

    _(:зゝ∠)_我又活着回来啦,前段时间太忙了写的题没时间扔上来,以后再说。

    【问题描述】

    成段加某一个值,然后询问区间和。

    【思路】

    讲一下pushdown和pushup出现的几个位置。

    pushup:

    (1)build的结尾,当叶子节点分别有对应的值后,它的父亲们就等于它们求和。

    (2)update的结尾,因为此时当前根的左右孩子已经更新了,故它也需要更新。

    pushdown(延迟标记):

    *pushdown会出现在一切要从当前结点往下的位置

    query和update中,要先把add的值传给两个儿子。

    接下来整理一下思路,每一个子过程分别需要如何操作:

    build(建立线段树)

    (1)将add清零

    (2)如果左子树等于右子树,则说明已经到达叶子节点,读入sum的值,返回

    (3)向左右子树递归

    (4)pushup更新当前根

    update(修改)

    (1)如果当前的L和R包含在l和r中,则让add+δ,让sum+δ*当前区间的长度,返回

    (2)pushdown向下延迟标记

    (3)向左右子树递归

    (4)pushup更新当前根

    query(查询)

    (1)如果当前的L和R包含在l和r中,则直接返回sum[rt]

    (2)pushdown向下延迟标记

    (3)向左右子树递归,将得到的返回值加到result总

    (4)返回result

    一般的线段树就是这样操作的,其实还挺简单(。・∀・)ノ゙最近学业有点忙好久没写程序了,整理一个当作恢复一下手速。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 #define lson l,m,rt<<1
     8 #define rson m+1,r,rt<<1|1
     9 #define LL long long
    10 const int MAXN=400000+500;
    11 int n,q;
    12 LL add[MAXN];
    13 LL sum[MAXN];
    14 
    15 void pushup(int rt)
    16 {
    17     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    18 }
    19 
    20 void build(int l,int r,int rt)
    21 {
    22     add[rt]=0;
    23     if (l==r)
    24     {
    25         scanf("%lld",&sum[rt]);
    26         return;
    27     }
    28     int m=(l+r)/2;
    29     build(lson);
    30     build(rson);
    31     pushup(rt);
    32 }
    33 
    34 void pushdown(int rt,int m)
    35 {
    36     if (add[rt])
    37     {
    38         add[rt<<1]+=add[rt];
    39         add[rt<<1|1]+=add[rt];
    40         sum[rt<<1]+=add[rt]*(m-(m>>1));
    41         sum[rt<<1|1]+=add[rt]*(m>>1);
    42         add[rt]=0;
    43     }
    44 }
    45 
    46 LL query(int L,int R,int l,int r,int rt)
    47 {
    48     if (L<=l && R>=r)
    49     {
    50         return sum[rt];
    51     }
    52     pushdown(rt,r-l+1);
    53     int m=(l+r)/2;
    54     LL rs=0;
    55     if (m>=L) rs+=query(L,R,lson);
    56     if (m<R)  rs+=query(L,R,rson);
    57     return rs;
    58 }
    59 
    60 void update(int L,int R,int delta,int l,int r,int rt)
    61 {
    62     if (L<=l && R>=r)
    63     {
    64         add[rt]+=delta;
    65         sum[rt]+=(LL)delta*(r-l+1);
    66         return;
    67     }
    68     pushdown(rt,r-l+1);
    69     int m=(l+r)/2;
    70     if (m>=L) update(L,R,delta,lson);
    71     if (m<R)  update(L,R,delta,rson);
    72     pushup(rt);
    73 }
    74 
    75 int main()
    76 {
    77     scanf("%d%d",&n,&q);
    78     build(1,n,1);
    79     for (int i=0;i<q;i++)
    80     {
    81         char c[2];
    82         scanf("%s",c);
    83         if (c[0]=='C')
    84         {
    85             int fr,ed,ad;
    86             scanf("%d%d%d",&fr,&ed,&ad);
    87             update(fr,ed,ad,1,n,1);
    88         }
    89         else
    90         {
    91             int a,b;
    92             scanf("%d%d",&a,&b);
    93             cout<<query(a,b,1,n,1)<<endl;
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    python中F/f表达式优于format()表达式
    java8新特性-foreach&lambda
    Java实现多线程的四种方式
    Java中的字符串常量池,栈和堆的概念
    java对象只有值传递,为什么?
    面向对象和面向过程程序设计理解及区别
    String对象为什么不可变
    mybatis_plus插件——生成器
    基于grpc的流式方式实现双向通讯(python)
    Django使用DataTables插件总结
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5001895.html
Copyright © 2011-2022 走看看