线段树单点修改,维护区间最大值

以hdoj1754为例:

#include <bits/stdc++.h>
using namespace std;

#define rg register
#define putln putchar('\n')
#define debug(x) cout<<"@ "<<(x)<<endl
#define rep(i,a,b) for(rg int i=a;i<=b;++i)
#define per(i,a,b) for(rg int i=a;i>=b;--i)

typedef long long ll;
const int MXN = 2e5+5;
int a[MXN];
int t[4*MXN],lazy[4*MXN]; //t是树,lazy是懒标记
int n,m,l,r;

inline lc(int x){return x<<1;}  //左儿子
inline rc(int x){return x<<1|1;}//右儿子

void up(int p)  //向上更新树
{
    t[p]=max(t[lc(p)],t[rc(p)]);
}
void build(int p,int l,int r)   //建树
{
    if(l==r){
        t[p]=a[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lc(p),l,mid);
    build(rc(p),mid+1,r);
    up(p);
}
void update(int xl,int xr,int x,int p,int l,int r)
{//xl,xr为要修改的区间
 //x为要修改成的值
 //p为当前节点编号
 //l,r为当前区间
    if(xl<=l && xr>=r){
        t[p]=x;
        return ;
    }
    int mid=(l+r)>>1;
    if(xl<=mid) update(xl,xr,x,lc(p),l,mid);
    if(xr>mid) update(xl,xr,x,rc(p),mid+1,r);
    up(p);
}
int query(int xl,int xr,int l,int r,int p)
{//xl,xr为要修改的区间
 //l,r为当前区间
 //p为当前节点编号
    if(xl<=l && r<=xr) return t[p];
    int mid=(l+r)>>1;
    int ans=0;
    if(xl<=mid) ans=max(query(xl,xr,l,mid,lc(p)),ans);
    if(xr>mid) ans=max(query(xl,xr,mid+1,r,rc(p)),ans);
    return ans;
}
int main()
{
    while(~scanf("%d %d",&n,&m)){
        rep(i,1,n) scanf("%d",&a[i]);
        build(1,1,n);
        rep(i,1,m){
            char c;
            getchar();
            scanf("%c %d %d",&c,&l,&r);
            if(c=='Q') printf("%d\n",query(l,r,1,n,1));
            else update(l,l,r,1,1,n);
        }
    }
    return 0;
}


上一篇:d-bus配置文件


下一篇:【转载】Postgres xc 和 xl