zoukankan      html  css  js  c++  java
  • 2018年6月2号(线段树(2))

      昨天只是普通的线段树(简单的单点修改

      而今天将讲是比较普通的简单的区间修改(加法修改):

      我主要是复制代码的蒟蒻我只能依靠模板为生,所以我想特地练下手:

     1 #include<bits/stdc++.h>//万能头文件
     2 using namespace std;
     3 struct node{
     4     int l,r;
     5     long long sum//总和,add//标记(延迟标记);
     6     #denfine l(x) tree[x].l;
     7     #denfine r(x) tree[x].r;
     8     #denfine sum(x) tree[x].sum;
     9     #denfine add(x) tree[x].add//宏定义
    10 }tree[100001*4];
    11 int a[100001*4],n,m;
    12 void build(int p,int l.int r)//建树
    13 {
    14     l(p)=l;r(p)=r;
    15     if(l==r) {sum(p)=a[l];return ;}
    16     int mid=(l+r)/2;
    17     build(p*2,l,mid);
    18     build(p*2+1,mid+1,r);
    19     sum(p)=sum(p*2)+sum(p*2+1);
    20 }
    21 void spread(int p)
    22 {
    23     if(add(p))//p节点进行标记;
    24    {
    25         sum(p*2)+=add(p)*(r(p*2)-l(p*2)+1);//更新左子节点信息
    26         sum(p*2+1)+=add(p)*(r(p*2+1)-l(p*2+1)+1);//更新右子节点;
    27         add(p*2)+=add(p);//给左子节点打延迟标记;
    28         add(p*2+1)+=add(p);//给右子节点打延迟标记;
    29         add(p)=0;//消除标记;
    30    }
    31 }
    32 void change(int p,int l,int r)
    33 {
    34     if(l<=l(p)&&r>=r(p))
    35     {
    36         sum(p)+=(long long)d*(r(p)-l(p)+1);
    37         add(p)+=d;
    38         return ;
    39     }
    40     spread(p);//下传延迟标记;
    41     int mid(l(p)+r(p))/2;
    42     if(l<=mid) change(p*2,l,r,d);
    43     if(r>mid) change(p*2+1,l,r,d);
    44     sum(p)=sum(p*2)+sum(p*2+1);
    45 }
    46 long long ask(int p,int l,int r)
    47 {
    48     if(l<=l(p)&&r>=r(p))
    49     return sum(p);
    50     spread(p);
    51     int mid=(l(p)+r(p))/2;
    52     long long val=0;
    53     if(l<=mid) val+=ask(p*2,l,r);
    54     if(r>=mid) val+=ask(p*2+1,l,r);
    55    return val;
    56 }
    57 int main()
    58 {
    59     cin>>n>>m;
    60     for(int i=1;i<=n;++i)
    61     scanf("%d",a[i]);
    62     build(1,1,n);//建树路口;
    63     while(m--)
    64     {
    65         char op[2];
    66         int l,r,d;
    67         scanf("%s%d%d",op,&l,&r);
    68         if(op[0]=='c')
    69        {
    70             scanf("%d".%d);
    71             chang(1,1,r,d);//进行修改
    72         }
    73         else printf("%lld
    ",ank(1,l,r));
    74     }
    75 }    

    好不容易打完了,可能会有很多错误,见谅!

  • 相关阅读:
    我的开发环境配置经验
    C# WINFORM 打包数据库
    C#格式化数值结果表(格式化字符串)
    Excel如何固定表头,任意一行
    下载fiddler证书并设置信任
    fiddler展示serverIP方法
    fiddler抓包参数乱码的解决方法
    fiddler模拟发送get/post请求(也可做简单接口测试)
    Jenkins常用插件
    关于gitignore文件的创建与使用
  • 原文地址:https://www.cnblogs.com/zssmg/p/9127571.html
Copyright © 2011-2022 走看看