以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;
}