题意:给定一个长度为n的区间,动态改变某个区间的值,问你最后整个区间的合是多少
解题思路:第一个区间覆盖的线段树问题,很自豪自己YY出了延迟标记(覆盖需要利用的延迟标记) 哈哈,就是利用的延迟标记覆盖区间,然后树根的值就是整个区间的值,每次覆盖后pushup就行
解题代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #define MAXN 100005 5 struct node 6 { 7 int left ,right,mid; 8 int num ; 9 int cover; 10 } tree[MAXN*4]; 11 int L(int c) 12 { 13 return 2*c; 14 } 15 int R(int c) 16 { 17 return 2*c + 1; 18 } 19 void up(int c) 20 { 21 tree[c].num = tree[L(c)].num + tree[R(c)].num; 22 } 23 void build(int c, int p ,int v ) 24 { 25 tree[c].left = p ; 26 tree[c].right = v ; 27 tree[c].mid = (p+v)/2; 28 tree[c].num = (v-p+1) ; 29 tree[c].cover = 1 ; 30 if(p == v) 31 { 32 return ; 33 } 34 build(L(c),p,tree[c].mid); 35 build(R(c),tree[c].mid+1,v); 36 } 37 38 void update(int c, int p , int v , int value) 39 { 40 if(p <= tree[c].left && v >= tree[c].right ) 41 { 42 tree[c].num = (tree[c].right - tree[c].left+1) * value ; 43 tree[c].cover = value; 44 return ; 45 } 46 if(tree[c].cover != 0 ) 47 { 48 tree[L(c)].cover = tree[c].cover; 49 tree[L(c)].num =(tree[L(c)].right - tree[L(c)].left+1) * tree[L(c)].cover; 50 tree[R(c)].cover = tree[c].cover; 51 tree[R(c)].num =(tree[R(c)].right - tree[R(c)].left+1) * tree[R(c)].cover; 52 tree[c].cover = 0 ; 53 } 54 if(v <= tree[c].mid) update(L(c),p,v,value); 55 else if(p > tree[c].mid) update(R(c),p,v,value); 56 else 57 { 58 update(L(c),p,tree[c].mid,value); 59 update(R(c),tree[c].mid+1,v,value); 60 } 61 up(c); 62 } 63 int main() 64 { 65 int T ; 66 scanf("%d",&T); 67 for(int CASE = 1; CASE <= T ; CASE ++ ) 68 { 69 int n ; 70 scanf("%d",&n); 71 build(1,1,n); 72 int m ; 73 scanf("%d",&m); 74 for(int i = 1; i <= m; i ++) 75 { 76 int a,b,value; 77 scanf("%d %d %d",&a,&b,&value); 78 update(1,a,b,value); 79 // printf("%d %d ",tree[2].num,tree[3].num); 80 } 81 82 printf("Case %d: The total value of the hook is %d. ",CASE,tree[1].num); 83 } 84 return 0 ; 85 }
ps:一看第一46ms,本来以为自己 1300 ms+是线段树写搓了,用胡浩的代码交上去既然也是1000+ , 应该是有什么更快的数据结构