/*×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× 线段树模板,先自学线段树原理 这里单点修改,区间查询最大值的代码 最小值只需要把max改成min即可 注意ans初始化 线段书的求和等其他操作稍后将更新于微博 本文章属个人作品,可以转载,因为 ------------------------------------我们是兄弟 ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××*/ #include<iostream> #include<string.h> #include<stdio.h> #define lson id*2 //左儿子 #define rson id*2+1 //右儿子 using namespace std; int tre[2000000]; //线段树 int ans=-19943; int a,b,c,d,n,m; int pushup(int id) //儿子节点的信息传递到父亲节点 //根据需要调节代码,下同 { tre[id]=max(tre[lson],tre[rson]); return 0; } int build(int id,int l,int r) //初始化 { if (l>r) return 0; if (l==r) { tre[id]=0; return 0; } int mid=(l+r)/2; build(lson,l,mid); build(rson,mid+1,r);//递归构造左右子树 pushup(id); return 0; } int add(int id,int l,int r,int pos,int num) //id是当前节点的编号,l&&r是id所代表区间的左右边界,pos是要插入的节点编号,num是要插入的数 { if (l>r) return 0;//线段树中容易发生这种错误,因为每次mid+1可能大于r if (l==r && r==pos) //如果l==r说明递归到了最底层,直接更新节点数值 { tre[id]=num; return 0; } int mid=(l+r)/2; if (pos<=mid) //如果要插入的点在mid左边,递归左边 add(lson,l,mid,pos,num); if (pos>=mid+1) //反之递归右边,注意这里是mid+1 add(rson,mid+1,r,pos,num); pushup(id); //更新当前节点的值 return 0; } int query(int id,int l,int r,int L,int R) //在编号为id的区间【l,r】中查找【L,R】区间的最大值 { if (l>r || L>R) return 0;//判断非法状态 if (L>r || R<l) return 0; if (l>=L && r<=R) { ans=max(ans,tre[id]); return 0; } int mid=(l+r)/2; if (mid>=L) //如果id区间的mid值包含在【L,R】之间,要递归查询id的左子树 query(lson,l,mid,L,R); if (mid+1<=R) query(rson,mid+1,r,L,R); return 0; } int main() { build(1,1,1000); add(1,1,1000,1,20); query(1,1,1000,1,10); cout<<ans<<endl; } 拿了代码的童鞋请点个赞吧,谢谢 线段树求和模板放在了http://blog.csdn.net/williamcode/article/details/50828407