zoukankan      html  css  js  c++  java
  • [模板]洛谷T3372 线段树 模板1

    变量定义:

    sum[]:线段树节点对应区间的元素总和;

    addv[]:线段树节点对应区间的所有元素的待追加值(懒标记),初值全部设为0。

    过程说明:

    建树(Build):

    若当前节点仅包含原序列中的一个值,即L=R,则直接赋值为序列中该值,否则递归建立左右子树后,将左右子树保存的sum值相加,即得到当前节点的sum值。

    懒标记下放(Push_down):

    将当前节点的addv值下放到左右子树。

    细节实现:

    1.子树的addv值加上当前节点的addv值;

    2.子树的sum值加上(子树包含元素数量*当前节点的addv值);

    3.清空当前节点的addv值,即赋值为0。

    特别说明:

    1.使用前判断,若当前节点的addv值为0则不需执行此下放函数。虽然执行了也不会有影响,但浪费时间。

    2.为尽量节省时间,要将判断放在此函数外而不是函数内。

    区间加(update):

    若当前节点完全包含在待更新区间内,则直接修改当前节点的addv值和sum值即可;

    否则:

    1.若当前节点addv值非0,则进行懒标记下放;

    2.若待更新区间与左子树对应区间有交集,则递归更新左子树,同理对右子树也执行类似操作。

    3.递归更新子树完成后,重新计算当前节点的sum值。

    区间查询(query):

    若当前节点完全包含在待查询区间内,则直接返回当前节点的sum值;

    否则:

    1.定义当前节点结果ans=0;

    2.若当前节点addv值非0,则进行懒标记下放;

    3.若待查询区间与左子树对应区间有交集,则递归查询左子树,并将所得结果加给ans,同理对右子树也执行类似操作。

    4.递归查询子树完成后,返回计算好的ans值。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<ctime>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<algorithm>
     8 #include<string>
     9 #include<stack>
    10 #include<queue>
    11 #include<vector>
    12 #include<map>
    13 using namespace std;
    14 long long c[2000010];
    15 struct sgt{
    16     long long sum[2000010];
    17     long long addv[2000010];       
    18     void build(int o,int l,int r){
    19         addv[o]=0;
    20         if(l==r)sum[o]=c[l];
    21         else{
    22             int mid=(l+r)>>1;
    23             int lson=o<<1;
    24             int rson=lson|1;
    25             build(lson,l,mid);
    26             build(rson,mid+1,r);
    27             sum[o]=sum[lson]+sum[rson];
    28         }
    29     }
    30     void push_down(int o,int l,int r,int mid,int lson,int rson){
    31         addv[lson]+=addv[o];
    32         addv[rson]+=addv[o];
    33         sum[lson]+=(mid-l+1)*addv[o];
    34         sum[rson]+=(r-mid)*addv[o];
    35         addv[o]=0;
    36     }
    37     void update(int o,int l,int r,int a,int b,int x){
    38         if(l>=a && r<=b){
    39             addv[o]+=x;
    40             sum[o]+=(r-l+1)*x;
    41             return;
    42         }
    43         else{
    44             int mid=(l+r)>>1;
    45             int lson=o<<1;
    46             int rson=lson|1;
    47             if(addv[o])push_down(o,l,r,mid,lson,rson);
    48             if(a<=mid)update(lson,l,mid,a,b,x);
    49             if(b>mid)update(rson,mid+1,r,a,b,x);
    50             sum[o]=sum[lson]+sum[rson];
    51         }
    52     }
    53     long long query(int o,int l,int r,int a,int b){
    54         if(l>=a && r<=b)return sum[o];
    55         else{
    56             int mid=(l+r)>>1;
    57             int lson=o<<1;
    58             int rson=lson|1;
    59             long long ans=0;
    60             if(addv[o])push_down(o,l,r,mid,lson,rson);
    61             if(a<=mid)ans+=query(lson,l,mid,a,b);
    62             if(b>mid)ans+=query(rson,mid+1,r,a,b);
    63             return ans;
    64         }
    65     }
    66 };
    67 sgt tree;
    68 int n,m,i,f;
    69 int x,y,k;
    70 int main(){
    71     scanf("%d%d",&n,&m);
    72     for(i=1;i<=n;i++)scanf("%d",&c[i]);
    73     tree.build(1,1,n);
    74     for(i=1;i<=m;i++){
    75         scanf("%d",&f);
    76         if(f&1){
    77             scanf("%d%d%d",&x,&y,&k);
    78             tree.update(1,1,n,x,y,k);
    79         }
    80         else{
    81             scanf("%d%d",&x,&y);
    82             printf("%lld
    ",tree.query(1,1,n,x,y));
    83         }
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    PAT 1006 Sign In and Sign Out
    PAT 1004. Counting Leaves
    JavaEE开发环境安装
    NoSql数据库探讨
    maven的配置
    VMWARE 下使用 32位 Ubuntu Linux ,不能给它分配超过3.5G 内存?
    XCODE 4.3 WITH NO GCC?
    在苹果虚拟机上跑 ROR —— Ruby on Rails On Vmware OSX 10.7.3
    推荐一首让人疯狂的好歌《Pumped Up Kicks》。好吧,顺便测下博客园可以写点无关技术的帖子吗?
    RUBY元编程学习之”编写你的第一种领域专属语言“
  • 原文地址:https://www.cnblogs.com/running-coder-wfh/p/6901456.html
Copyright © 2011-2022 走看看