线段树+树状数组题目导引

PS:http://www.notonlysuccess.com/index.php/segment-tree-complete/

线段树很好的博客;

HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1754

求区间的最大值:#include <cstdio>

#include<algorithm>
#include<math.h>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 255555;
int sum[maxn<<2];
void PushUP(int rt) {
    sum[rt] = max(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 = max(ret,query(L , R , lson));
    if (R > m) ret = max(ret,query(L , R , rson));
    return ret;
}
int main() {
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF) {
        memset(sum,0,sizeof(sum));
        build(1 , n , 1);
        while (m--) {
            char s[2];
            int a,b;
            scanf("%s%d%d",s,&a,&b);
            if (s[0]=='Q') printf("%d ",query(a,b,1,n,1));
            else update(a,b,1,n,1);
        }
    }
    return 0;
}

HDU 1166;更新点值求区间

 修改区间求区间值:

题目:http://acm.fzu.edu.cn/problem.php?pid=2171

模板: http://www.cnblogs.com/forgot93/p/3700449.html

PKU2777:抄HH模板过头了,自己根本没理解深透,然后TLE了好久;

HDU 3308LCIS:

找BUG找了很久,虽然思路不是自己的,怪自己没理解偷模板,然后就输出一些奇怪的东西。。。

小小总结一下:

          

 跟新区间用 LAZY标记法,然后又一个 PUSHDOWN,和PUSHUP操作,

更新点的话就有一个PUSHUP操作就可以了

2:多次询问一个连续区间的某些特征时,一般要把改区间分为左右两区间进行操作。 

原文地址:https://www.cnblogs.com/forgot93/p/3708835.html