zoukankan      html  css  js  c++  java
  • 搬运——线段树模板

    最近各种线段树,然后一直用HH模板!然后老是写不出!

    与之搬运过来!

    线段树功能:update:单点增减 query:区间求和

    #include <cstdio>
     
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 55555;
    int sum[maxn<<2];
    void PushUP(int rt) {
    	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void build(int l,int r,int rt) {
    	if (l == r) {
    		scanf("%d",&sum[rt]);
    		return ;
    	}
    	int m = (l + r) >> 1;
    	build(lson);
    	build(rson);
    	PushUP(rt);
    }
    void update(int p,int add,int l,int r,int rt) {
    	if (l == r) {
    		sum[rt] += add;
    		return ;
    	}
    	int m = (l + r) >> 1;
    	if (p <= m) update(p , add , lson);
    	else update(p , add , rson);
    	PushUP(rt);
    }
    int query(int L,int R,int l,int r,int rt) {
    	if (L <= l && r <= R) {
    		return sum[rt];
    	}
    	int m = (l + r) >> 1;
    	int ret = 0;
    	if (L <= m) ret += query(L , R , lson);
    	if (R > m) ret += query(L , R , rson);
    	return ret;
    }
    int main() {
    	int T , n;
    	scanf("%d",&T);
    	for (int cas = 1 ; cas <= T ; cas ++) {
    		printf("Case %d:
    ",cas);
    		scanf("%d",&n);
    		build(1 , n , 1);
    		char op[10];
    		while (scanf("%s",op)) {
    			if (op[0] == 'E') break;
    			int a , b;
    			scanf("%d%d",&a,&b);
    			if (op[0] == 'Q') printf("%d
    ",query(a , b , 1 , n , 1));
    			else if (op[0] == 'S') update(a , -b , 1 , n , 1);
    			else update(a , b , 1 , n , 1);
    		}
    	}
    	return 0;
    }
    

      线段树功能:update:单点替换 query:区间最值

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4  
     5 #define lson l , m , rt << 1
     6 #define rson m + 1 , r , rt << 1 | 1
     7 const int maxn = 222222;
     8 int MAX[maxn<<2];
     9 void PushUP(int rt) {
    10     MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]);
    11 }
    12 void build(int l,int r,int rt) {
    13     if (l == r) {
    14         scanf("%d",&MAX[rt]);
    15         return ;
    16     }
    17     int m = (l + r) >> 1;
    18     build(lson);
    19     build(rson);
    20     PushUP(rt);
    21 }
    22 void update(int p,int sc,int l,int r,int rt) {
    23     if (l == r) {
    24         MAX[rt] = sc;
    25         return ;
    26     }
    27     int m = (l + r) >> 1;
    28     if (p <= m) update(p , sc , lson);
    29     else update(p , sc , rson);
    30     PushUP(rt);
    31 }
    32 int query(int L,int R,int l,int r,int rt) {
    33     if (L <= l && r <= R) {
    34         return MAX[rt];
    35     }
    36     int m = (l + r) >> 1;
    37     int ret = 0;
    38     if (L <= m) ret = max(ret , query(L , R , lson));
    39     if (R > m) ret = max(ret , query(L , R , rson));
    40     return ret;
    41 }
    42 int main() {
    43     int n , m;
    44     while (~scanf("%d%d",&n,&m)) {
    45         build(1 , n , 1);
    46         while (m --) {
    47             char op[2];
    48             int a , b;
    49             scanf("%s%d%d",op,&a,&b);
    50             if (op[0] == 'Q') printf("%d
    ",query(a , b , 1 , n , 1));
    51             else update(a , b , 1 , n , 1);
    52         }
    53     }
    54     return 0;
    55 }
    View Code

    线段树功能:update:成段增减 query:区间求和

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4  
     5 #define lson l , m , rt << 1
     6 #define rson m + 1 , r , rt << 1 | 1
     7 #define LL long long
     8 const int maxn = 111111;
     9 LL add[maxn<<2];
    10 LL sum[maxn<<2];
    11 void PushUp(int rt) {
    12     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    13 }
    14 void PushDown(int rt,int m) {
    15     if (add[rt]) {
    16         add[rt<<1] += add[rt];
    17         add[rt<<1|1] += add[rt];
    18         sum[rt<<1] += add[rt] * (m - (m >> 1));
    19         sum[rt<<1|1] += add[rt] * (m >> 1);
    20         add[rt] = 0;
    21     }
    22 }
    23 void build(int l,int r,int rt) {
    24     add[rt] = 0;
    25     if (l == r) {
    26         scanf("%lld",&sum[rt]);
    27         return ;
    28     }
    29     int m = (l + r) >> 1;
    30     build(lson);
    31     build(rson);
    32     PushUp(rt);
    33 }
    34 void update(int L,int R,int c,int l,int r,int rt) {
    35     if (L <= l && r <= R) {
    36         add[rt] += c;
    37         sum[rt] += (LL)c * (r - l + 1);
    38         return ;
    39     }
    40     PushDown(rt , r - l + 1);
    41     int m = (l + r) >> 1;
    42     if (L <= m) update(L , R , c , lson);
    43     if (m < R) update(L , R , c , rson);
    44     PushUp(rt);
    45 }
    46 LL query(int L,int R,int l,int r,int rt) {
    47     if (L <= l && r <= R) {
    48         return sum[rt];
    49     }
    50     PushDown(rt , r - l + 1);
    51     int m = (l + r) >> 1;
    52     LL ret = 0;
    53     if (L <= m) ret += query(L , R , lson);
    54     if (m < R) ret += query(L , R , rson);
    55     return ret;
    56 }
    57 int main() {
    58     int N , Q;
    59     scanf("%d%d",&N,&Q);
    60     build(1 , N , 1);
    61     while (Q --) {
    62         char op[2];
    63         int a , b , c;
    64         scanf("%s",op);
    65         if (op[0] == 'Q') {
    66             scanf("%d%d",&a,&b);
    67             printf("%lld
    ",query(a , b , 1 , N , 1));
    68         } else {
    69             scanf("%d%d%d",&a,&b,&c);
    70             update(a , b , c , 1 , N , 1);
    71         }
    72     }
    73     return 0;
    74 }

     另一种版本 求区间最小值

     1 struct node
     2 {
     3    int l,r,val;
     4 }tree[N*8];
     5 
     6 void pushup(int rt)
     7 {
     8  tree[rt].val=min(tree[rt<<1].val,tree[rt<<1|1].val);
     9 }
    10 
    11 void build(int l,int r,int rt)
    12 {
    13   tree[rt].l=l;
    14   tree[rt].r=r;
    15   if (l==r)
    16   {
    17     tree[rt].val=A[l];
    18     return;
    19   }
    20 
    21   int m=(l+r)>>1;
    22   build(l,m,rt<<1);
    23   build(m+1,r,rt<<1|1);
    24   pushup(rt);
    25 }
    26 
    27 
    28 int query(int l,int r,int rt)
    29 {
    30   if (tree[rt].l>=l&&tree[rt].r<=r) return tree[rt].val;
    31   int m=(tree[rt].l+tree[rt].r)>>1;
    32   if (r<=m) return query(l,r,rt<<1);
    33   else if (l>m) return query(l,r,rt<<1|1);
    34   else return min(query(l,m,rt<<1),query(m+1,r,rt<<1|1));
    35 }
  • 相关阅读:
    Python入门 日志打印
    Python入门 面向对象
    Python入门 更换pip源的方法
    Python入门 模块
    Python入门 函数式编程
    四月份该做的事情
    Docker入门 配置篇
    Python入门 序列章
    Python入门 值内存管理与所有的关键字
    论操作系统的IO
  • 原文地址:https://www.cnblogs.com/forgot93/p/4008848.html
Copyright © 2011-2022 走看看