模板 线段树的区间修改
Posted third2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 线段树的区间修改相关的知识,希望对你有一定的参考价值。
线段树的区间修改
区间绝对标记 改成同一个数
注意打标记前 要先判断 是否有标记
这道题不能像加法标记一样 标记初始化为 0
如果这道题 可以将数变成 0 那么0 就不能为初始值了
然后我们初始值要选择一个不会被干扰到的数字
比如 -1 就不会变成 -1
另外还要注意在标记清空时 要将标记 变成 -1 而不是 0
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 #include <iomanip> 9 #define ll long long 10 using namespace std ; 11 12 const int maxn = 1e5+11 ; 13 struct node{ 14 int l,r ; 15 ll sum,mark ; 16 }tree[maxn*4]; 17 int n,Q,type,L,R,v ; 18 int a[maxn] ; 19 ll ans ; 20 21 inline int read() 22 { 23 char ch = getchar() ; 24 int x = 0 , f = 1 ; 25 while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) f = -1 ; ch = getchar() ; } 26 while(ch>=‘0‘&&ch<=‘9‘) { x = x*10+ch-48 ; ch = getchar() ; } 27 return x * f ; 28 } 29 30 inline void pushup(int root) 31 { 32 tree[root].sum = tree[root*2].sum + tree[root*2+1].sum ; 33 } 34 35 inline void build(int l,int r,int root) 36 { 37 tree[root].l = l ; tree[root].r = r ; 38 tree[root].mark = -1 ; 39 if(l==r) 40 { 41 tree[root].sum = a[ l ] ; tree[root].mark = 0 ; 42 return ; 43 } 44 int mid = (l + r) >>1 ; 45 build(l,mid,root*2) ; 46 build(mid+1,r,root*2+1) ; 47 pushup(root) ; 48 } 49 50 inline void pushdown(int root) 51 { 52 if(tree[root].mark == -1) return ; 53 tree[root*2].mark = tree[root].mark ; 54 tree[root*2].sum = ( 1ll*tree[root*2].r - tree[root*2].l+1) * tree[root].mark ; 55 tree[root*2+1].mark = tree[root].mark ; 56 tree[root*2+1].sum = ( 1ll*tree[root*2+1].r - tree[root*2+1].l+1) * tree[root].mark ; 57 tree[root].mark = -1 ; // 58 } 59 60 inline void updata(int l,int r,int v,int root) 61 { 62 if(l==tree[root].l&&r==tree[root].r) 63 { 64 tree[root].sum = (1ll*tree[root].r-tree[root].l+1) * v ; 65 tree[root].mark = v ; 66 return ; 67 } 68 pushdown(root) ; 69 int mid = (tree[root].l + tree[root].r) >>1 ; 70 if( r<=mid ) updata(l,r,v,root*2) ; 71 else 72 if( l > mid) updata(l,r,v,root*2+1) ; 73 else 74 { 75 updata(l,mid,v,root*2) ; 76 updata(mid+1,r,v,root*2+1) ; 77 } 78 pushup(root) ; 79 } 80 81 inline ll query(int l,int r,int root) 82 { 83 if(tree[root].l==l&&tree[root].r==r) 84 return tree[root].sum ; 85 pushdown(root) ; // 86 int mid = (tree[root].l + tree[root].r ) >>1; 87 if( r<=mid ) return query(l,r,root*2) ; 88 if( l > mid ) return query(l,r,root*2+1) ; 89 ll ans = 0 ; 90 ans+=query(l,mid,root*2) ; 91 ans+=query(mid+1,r,root*2+1) ; 92 return ans ; 93 } 94 95 int main() 96 { 97 n = read() ; 98 for(int i=1;i<=n;i++) a[ i ] = read() ; 99 Q = read() ; 100 build(1,n,1) ; 101 102 for(int i=1;i<=Q;i++) 103 { 104 type = read() ; L = read() ; R = read() ; 105 if(type==1) 106 { 107 v = read() ; 108 updata(L,R,v,1) ; 109 } 110 else 111 { 112 ans = query(L,R,1) ; 113 printf("%lld\n",ans) ; 114 } 115 } 116 return 0 ; 117 }
以上是关于模板 线段树的区间修改的主要内容,如果未能解决你的问题,请参考以下文章