线段树 --- 适用于修改性的求区间问题 【单点修改】

来源:互联网 发布:互联网软件开发工资 编辑:程序博客网 时间:2024/05/27 01:18

这里说的是单点修改.
模板题
不同于RMQ,RMQ修改后再去处理,复杂度就会很高. 而线段树修改和询问都还是会保持在logn的复杂度之内.

AC Code 和 板子: (求区间最大,最小,区间和稍微修改下就行了, 如果有多种东西(比如说有lazy标记, 或者同时维护多种关系等)要存,直接在结构体中添加相应的元素即可,然后修改一些地方的判断)
//直接用就行了.

const int maxn = 1e6+5;int n;int a[maxn];struct Tree{    int tl,tr;    int minn,maxx;}tree[maxn<<2];void pushup(int id){    tree[id].minn = min(tree[id<<1].minn , tree[id<<1|1].minn);    tree[id].maxx = max(tree[id<<1].maxx , tree[id<<1|1].maxx);}void build(int l,int r,int id){    tree[id].tl = l, tree[id].tr = r;    if(l == r){        tree[id].maxx = tree[id].minn = a[l];        return ;    }    int mid = (r+l)>>1;    build(l,mid,id<<1);    build(mid+1,r,id<<1|1);    pushup(id);}void update(int pos,int val,int id){    int l = tree[id].tl, r = tree[id].tr;    if(l == r){        tree[id].maxx = tree[id].minn = val;        return ;    }    int mid = (l+r) >> 1;    if(pos <= mid) update(pos,val,id<<1);    else update(pos,val,id<<1|1);    pushup(id);}int mi,mx;void query(int ql,int qr,int id){    int l = tree[id].tl, r = tree[id].tr;    if(ql <= l && qr >= r ){        mi = min(mi,tree[id].minn);        mx = max(mx,tree[id].maxx);        return ;    }    int mid = (l + r) >> 1;    if(ql <= mid) query(ql,qr,id<<1);    if(qr > mid) query(ql,qr,id<<1|1);}void solve(){    scanf("%d",&n);    for(int i=1;i<=n;i++){        scanf("%d",&a[i]);    }    build(1,n,1);    int q; scanf("%d",&q);    while(q--){        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        mi = inf;    // mx = 0;   反正需要就改就是了.        if(a == 0) query(b,c,1),printf("%d\n",mi);  //或者是mx.        else update(b,c,1);    }}
原创粉丝点击