参考qsc大佬的视频 太强惹 先膜一下 视频在b站 直接搜线段树即可
1 #include<cstdio> 2 using namespace std; 3 const int maxn=1e5+6; 4 int n,a[maxn]; 5 struct Node{ 6 int l,r; 7 long long sum,lazy; 8 void update(long long x){//用于更新区间和 和懒标记 9 sum+=1ll*(r-l+1)*x; 10 lazy+=x; 11 } 12 }tree[maxn*4]; 13 void push_up(int x){//用于用子区间重新计算该区间的区间和 14 tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; 15 } 16 void push_down(int x){//把lazy标记往下面传递 17 int lazyval=tree[x].lazy; 18 if(lazyval){ 19 tree[x<<1].update(lazyval); 20 tree[x<<1|1].update(lazyval); 21 tree[x].lazy=0; 22 } 23 } 24 void build(int x,int l,int r){//建树 25 tree[x].l=l,tree[x].r=r; 26 tree[x].sum=tree[x].lazy=0; 27 if(l==r){ 28 tree[x].sum=a[l]; 29 } 30 else { 31 int mid=l+r>>1; 32 build(x<<1,l,mid); 33 build(x<<1|1,mid+1,r); 34 push_up(x); 35 } 36 } 37 void update(int x,int l,int r,long long val){//区间修改 38 int L=tree[x].l,R=tree[x].r; 39 if(l<=L&&R<=r){//完全包含直接修改就行 40 tree[x].update(val); 41 } 42 else {//push_down 把懒标记往下面传 43 push_down(x);//不是完全包含 继续往下面修改包含的区间l ,r 不用改它是用来判断当前区间位不位于要修改的区间里面的,如果位于那么就要修改 44 int mid=L+R>>1; 45 if(mid>=l)update(x<<1,l,r,val); 46 if(r>mid)update(x<<1|1,l,r,val); 47 push_up(x);//已经更新好了子区间重新计算区间和 48 } 49 } 50 long long query(int x,int l,int r){//查询l,r区间 x是节点标号 和上面update类似 51 int L=tree[x].l,R=tree[x].r; 52 if(l<=L&&R<=r){ 53 return tree[x].sum; 54 } 55 else { 56 push_down(x); 57 long long ans=0; 58 int mid=L+R>>1; 59 if(mid>=l)ans+=query(x<<1,l,r); 60 if(r>mid)ans+=query(x<<1|1,l,r); 61 push_up(x); 62 return ans; 63 } 64 } 65 int main(){ 66 int q; 67 scanf("%d%d",&n,&q); 68 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 69 build(1,1,n); 70 for(int i=1;i<=q;i++){ 71 int l,r,val; 72 char op[10]; 73 scanf("%s",op); 74 if(op[0]==‘C‘){ 75 scanf("%d%d%d",&l,&r,&val); 76 update(1,l,r,val); 77 } 78 else { 79 scanf("%d%d",&l,&r); 80 printf("%lld\n",query(1,l,r)); 81 } 82 } 83 84 return 0; 85 }
原文地址:https://www.cnblogs.com/ttttttttrx/p/10292725.html
时间: 2024-10-07 08:20:50