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 }    

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

原文地址:https://www.cnblogs.com/zssmg/p/9127571.html