2018年6月2号(线段树)
Posted zssmg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018年6月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\n",ank(1,l,r)); 74 } 75 }
好不容易打完了,可能会有很多错误,见谅!
以上是关于2018年6月2号(线段树)的主要内容,如果未能解决你的问题,请参考以下文章