线段树,我学习的是KUANGBIN 大神的模板吧,,,
void PushUP(int rt){
sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}
void build(int l,int r,int rt){
if(r==l){
scanf("%d",&sum[rt]);
return ;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
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,l,m,rt<<1);
else update(p,add,m+1,r,rt<<1|1);
PushUP(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
//printf("l=%d r=%d sum=%d\n",l,r,sum[rt]);
return sum[rt];
}
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret=max(ret,query(L,R,l,m,rt<<1));
if(R>m) ret=max(ret,query(L,R,m+1,r,rt<<1|1));
return ret;
}
因为这种树,几乎是完全二叉树,所以用数组存就蛮好,数组基本要开到极限的范围的四倍左右。
建树,很明显没有用结构体,而是通过递归实现记录,更新,用递归找到要存的的位置侯依次输入要存的值。
#include<bits/stdc++.h>
#define maxn 200010
using namespace std;
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(r==l){
scanf("%d",&sum[rt]);
return ;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
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,l,m,rt<<1);
else update(p,add,m+1,r,rt<<1|1);
PushUP(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
//printf("l=%d r=%d sum=%d\n",l,r,sum[rt]);
return sum[rt];
}
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret=max(ret,query(L,R,l,m,rt<<1));
if(R>m) ret=max(ret,query(L,R,m+1,r,rt<<1|1));
return ret;
}
int main()
{
int T,n,m;
//scanf("%d",&T);
while(~scanf("%d%d",&n,&m))
{
//printf("Case %d:\n",ca);
build(1,n,1);
char ss[10];
while(m--)
{
scanf("%s",ss);
//if(ss[0]=='E') break;
int a,b;
scanf("%d%d",&a,&b);
if(ss[0]=='Q') printf("%d\n",query(a,b,1,n,1));
//else if( ss[0]=='U') update(a,-b,1,n,1);
else update(a,b,1,n,1);
}
}
return 0;
}