线段树之单点更新

Posted starry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树之单点更新相关的知识,希望对你有一定的参考价值。

单点更新,其实就是对一个点进行更新。

HDU 1166

  
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define lson l,m,rt<<1
 5 #define rson m+1,r,rt<<1|1
 6 using namespace std;
 7 const int MAX = 50010;
 8 int tree[MAX<<2];
 9 void Push(int rt){
10     tree[rt] = tree[rt<<1]+tree[rt<<1|1];
11 }
12 void build(int l, int r, int rt){
13     if(l == r){
14         scanf("%d",&tree[rt]);
15         return ;
16     }
17     int m = (l+r)>>1;
18     build(lson);
19     build(rson);
20     Push(rt);
21 }
22 void update(int x, int p, int l, int r, int rt){
23     if(l == r){
24         tree[rt] += p;
25         return;
26     }
27     int m = (l+r)>>1;
28     if(m >=x)update(x,p,lson);
29     else update(x,p,rson);
30     Push(rt);
31 }
32 int query(int LL, int RR, int l, int r, int rt){
33     if(LL <= l && r <= RR){
34         return tree[rt];
35     }
36     int m = (l+r)>>1;
37     int sum = 0;
38     if(m >= LL) sum+=query(LL,RR,lson);
39     if(m < RR) sum+=query(LL,RR,rson);
40     return sum;
41 }
42 int main(){
43     int t,n,k=1;
44     scanf("%d",&t);
45     while(t--){
46         scanf("%d",&n);
47         printf("Case %d:\n",k++);
48         build(1,n,1);
49         char str[10];
50         int l,r;
51         while(scanf("%s",str)!=EOF){
52             if(str[0] == E)break;
53             scanf("%d %d",&l,&r);
54             if(str[0] == Q){
55                 printf("%d\n",query(l,r,1,n,1));
56             }else if(str[0] == A){
57                 update(l,r,1,n,1);
58             }else {
59                 update(l,-r,1,n,1);
60             }
61         }
62     }
63     return 0;
64 }

 

HDU - 2795

 1 #include <iostream>
 2 #include <cstdio>
 3 #define lson l, m, rt<<1
 4 #define rson m+1, r, rt<<1|1
 5 
 6 using namespace std;
 7 const int maxn = 2e5+10;
 8 int n, h, w;
 9 int MAX[maxn<<2];
10 void PushUP(int rt){
11     MAX[rt] = max(MAX[rt<<1], MAX[rt<<1|1]);
12 }
13 
14 void build(int l, int r, int rt){//建立线段树
15     MAX[rt] = w;
16     if(l == r)return;
17     int m = (l + r) >> 1;
18     build(lson);
19     build(rson);
20 }
21 int query(int q, int l, int r, int rt){
22     if(l == r){
23         MAX[rt] -= q;//每次查询时减下q
24         return l;
25     }
26     int m = (l + r) >> 1;
27     int ret = (MAX[rt<<1] >= q)?query(q, lson):query(q, rson);//求出满足条件的最左边区间
28     PushUP(rt);
29     return ret;
30 }
31 
32 int main()
33 {
34     while(~scanf("%d%d%d",&h,&w,&n)){
35         if(h > n) h = n;//这样建立的区间更少些
36         build(1, h, 1);
37         while(n--){
38             int x;
39             scanf("%d",&x);
40             if(MAX[1] < x) printf("-1\n");
41             else printf("%d\n",query(x, 1, h, 1));
42         }
43     }
44     return 0;
45 }

 

以上是关于线段树之单点更新的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1754 I Hate It(线段树之单点更新,区间最值)

hdu 1754 I Hate It(线段树之 单点更新+区间最值)

HDU 1754 I Hate It(线段树之单点更新 区间最值查询)

进阶线段树之乘法操作

线段树之各类模板

算法模板——线段树之Lazy标记