线段树区间更新和区间查询模板题,加懒标记防止其时间复杂度退化
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 #define ls (pos<<1) 7 #define rs (pos<<1|1) 8 const int MAXN=100000+10; 9 struct node 10 { 11 int l,r,add; 12 long long sum; 13 int mid() 14 { 15 return (l+r)>>1; 16 } 17 }; 18 node tree[MAXN<<2]; 19 int a[MAXN]; 20 void maintain(int pos) 21 { 22 tree[pos].sum=tree[ls].sum+tree[rs].sum; 23 } 24 void build(int l,int r,int pos) 25 { 26 tree[pos].l=l; 27 tree[pos].r=r; 28 tree[pos].add=0; 29 if(l==r) 30 { 31 tree[pos].sum=(long long)a[l]; 32 return; 33 } 34 int mid=tree[pos].mid(); 35 build(l,mid,ls); 36 build(mid+1,r,rs); 37 maintain(pos); 38 } 39 void pushdown(int pos,int m) 40 { 41 if(tree[pos].add) 42 { 43 if(tree[pos].l==tree[pos].r) 44 { 45 tree[pos].add=0; 46 return; 47 } 48 tree[ls].add+=tree[pos].add; 49 tree[rs].add+=tree[pos].add; 50 tree[ls].sum+=(long long)(m-(m>>1))*tree[pos].add; 51 tree[rs].sum+=(long long)(m>>1)*tree[pos].add; 52 tree[pos].add=0; 53 } 54 } 55 void update(int l,int r,int c,int pos) 56 { 57 if(l<=tree[pos].l&&tree[pos].r<=r) 58 { 59 tree[pos].add+=c; 60 tree[pos].sum+=(long long)(tree[pos].r-tree[pos].l+1)*c; 61 return; 62 } 63 pushdown(pos,(tree[pos].r-tree[pos].l+1)); 64 int mid=tree[pos].mid(); 65 if(r<=mid) update(l,r,c,ls); 66 else if(l>mid) update(l,r,c,rs); 67 else 68 { 69 update(l,mid,c,ls); 70 update(mid+1,r,c,rs); 71 } 72 maintain(pos); 73 } 74 long long query(int l,int r,int pos) 75 { 76 if(l<=tree[pos].l&&tree[pos].r<=r) 77 { 78 return tree[pos].sum; 79 } 80 pushdown(pos,(tree[pos].r-tree[pos].l+1)); 81 int mid=tree[pos].mid(); 82 long long ans=0; 83 if(r<=mid) ans=query(l,r,ls); 84 else if(l>mid) ans=query(l,r,rs); 85 else 86 { 87 ans=query(l,mid,ls)+query(mid+1,r,rs); 88 } 89 return ans; 90 } 91 int main() 92 { 93 int n,q; 94 while(scanf("%d%d",&n,&q)==2) 95 { 96 for(int i=1;i<=n;i++) 97 scanf("%d",&a[i]); 98 build(1,n,1); 99 char c; 100 int l,r,k; 101 while(q--) 102 { 103 scanf(" %c",&c); 104 if(c=='Q') 105 { 106 scanf("%d%d",&l,&r); 107 long long ans=query(l,r,1); 108 printf("%lld\n",ans); 109 } 110 else 111 { 112 scanf("%d%d%d",&l,&r,&k); 113 update(l,r,k,1); 114 } 115 } 116 } 117 return 0;