hud 1754 http://acm.hdu.edu.cn/showproblem.php?pid=1754
(0)定义
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn =222222;
int MAX[maxn<<2]; // maxn *4;
(1) 建立线段树
void PushUp(int rt) // rt :当前节点的编号
{ //更新该节点的数据 ,这里是求该节点的最大值 MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); // <<1==*2 ,<<1|1==*2+1; } void build(int l,int r,int rt)//建树 ,[l.r]当前节点的区间,rt :当前的节点 { if(r==l){ //到达子叶节点, scanf("%d",&MAX[rt]); return ; } int m=(l+r)>>1; // 除以2 //左右递归 build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(rt); //更新信息 }
(2)单点替换
void update(int p,int sc,int l,int r,int rt){ // P:替换第几个,sc:更换的数据 在[l.r]中查找 if(l==r){ MAX[rt]=sc; return ; } int m=(l+r)>>1; //判断 p 左还是右 if(p<=m){ update(p,sc,l,m,rt<<1); }else{ update(p,sc,m+1,r,rt<<1|1); } PushUp(rt);// 子叶替换后 当前节点更新 }
(3) 区间最大值
int query(int L,int R,int l,int r,int rt){ //[L,R] 所求区间 [l,r]当前区间 if(L<=l&&r<=R){ return MAX[rt]; } int m=(l+r)>>1; int ret=0; if(L<=m)ret=max(ret,query(L,R,l,m,rt<<1)); if(m<R)ret=max(ret,query(L,R,m+1,r,rt<<1|1)); return ret; }
线段树,不会的话可以多画画自己理解理解;
附上全部代码
#include<iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn =222222; int MAX[maxn<<2]; // maxn *4; void PushUp(int rt) // rt :当前节点的编号 { //更新该节点的数据 ,这里是求该节点的最大值 MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); // <<1==*2 ,<<1|1==*2+1; } void build(int l,int r,int rt)//建树 ,[l.r]当前节点的区间,rt :当前的节点 { if(r==l){ //到达子叶节点, scanf("%d",&MAX[rt]); return ; } int m=(l+r)>>1; // 除以2 //左右递归 build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(rt); //更新信息 } //单点替换 void update(int p,int sc,int l,int r,int rt){ // P:替换第几个,sc:更换的数据 在[l.r]中查找 if(l==r){ MAX[rt]=sc; return ; } int m=(l+r)>>1; //判断 p 左还是右 if(p<=m){ update(p,sc,l,m,rt<<1); }else{ update(p,sc,m+1,r,rt<<1|1); } PushUp(rt);// 子叶替换后 当前节点更新 } //区间最大值 int query(int L,int R,int l,int r,int rt){ //[L,R] 所求区间 [l,r]当前区间 if(L<=l&&r<=R){ return MAX[rt]; } int m=(l+r)>>1; int ret=0; if(L<=m)ret=max(ret,query(L,R,l,m,rt<<1)); if(m<R)ret=max(ret,query(L,R,m+1,r,rt<<1|1)); return ret; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ build(1,n,1);// 建树 从 1 到 n ,当前节点为1 while(m--){ char op[2]; int a,b; scanf("%s%d%d",op,&a,&b); if(op[0]=='Q'){ int k=query(a,b,1,n,1); printf("%d\n",k); //cout<<k<<endl; } else update(a,b,1,n,1); } } return 0; }