线段树实现RMQ问题(线段树模板的基本应用)
2011-10-20 19:10
363 查看
RMQ问题如果用线段树实现的话,可以实现O(nlogN)的预处理,O(logN)的查询,速度还可以。
以求最大值为例,将key定义为区间的最大值。建立树时初始化为负无穷大
把任意点a 看成区间[a,a],先把所有的点插入线段树。然后每次用线段树去查询
代码如下:
以求最大值为例,将key定义为区间的最大值。建立树时初始化为负无穷大
把任意点a 看成区间[a,a],先把所有的点插入线段树。然后每次用线段树去查询
代码如下:
#include<iostream> #include<algorithm> using namespace std; const int MIN=-2000000000; //线段树的节点,包括基本域 :左右边界,左右孩子的指针 信息域:key struct Node{ int ld,rd;//左右边界 Node *lc,*rc;//左右孩子 int key;//信息域,此例子为RMQ,所以存储的为区间最大值 }; //建立一个从区间a到b的空线段树,key初始化为最小负值 Node* buildtree(int a,int b){ Node *p=new Node; p->ld=a; p->rd=b; p->key=MIN; if(a==b)return p; p->lc=buildtree(a,(a+b)/2); p->rc=buildtree((a+b)/2+1,b); return p; } void insert(Node *T,int pos,int key){ if(T->ld==T->rd){ T->key=key; return; } if(pos<=(T->ld+T->rd)/2) insert(T->lc,pos,key); else insert(T->rc,pos,key); T->key=max(T->lc->key,T->rc->key); } int search(Node *T,int a,int b){ int res=MIN; if(a<=T->ld&&b>=T->rd) return T->key; if(a<=(T->ld+T->rd)/2){ int temp=search(T->lc,a,b); if(res<temp)res=temp; } if(b>(T->ld+T->rd)/2){ int temp=search(T->rc,a,b); if(res<temp)res=temp; } return res; } int main(){ int n,val; cin>>n; Node* root=buildtree(1,n); for(int i=1;i<=n;i++){ cin>>val; insert(root,i,val); } int ld,rd; while(cin>>ld>>rd&&ld!=0){ cout<<search(root,ld,rd)<<endl; } return 0; } /* 10 1 3 8 2 9 7 5 6 4 0 */
相关文章推荐
- RMQ问题详解 --Sparse-Table算法实现和线段树实现
- ACM模板——区间问题(线段树 RMQ-ST)模板
- HDU 1166 敌兵布阵 线段树的基本应用——动态区间和问题
- RMQ 线段树实现+DP实现 模板
- Hihocoder #1077 : RMQ问题再临-线段树(线段树:结构体建树+更新叶子往上+查询+巧妙使用father[]+线段树数组要开大4倍 *【模板】)
- poj3264(RMQ问题的线段树实现方法)
- poj 3264 RMQ问题 zkw线段树
- 加密、解密、openssl的基本应用及CA的实现过程
- 实验4:栈和队列的基本操作实现及其应用——链栈
- 加密、解密、openssl的基本应用及CA的实现过程
- RMQ问题-very easy-打印模板
- #1077 : RMQ问题再临-线段树
- Linux—加密解密openssl的基本应用及CA的实现过程
- C++类模板定义与实现的分离—学习C++数据抽象和问题求解
- 疑难杂症:解决由早期版本的Web应用项目模板造成的VS 2005 SP1 Beta的问题
- josephus问题(基本对象的实现方法)
- c/c++模板的定义和实现分开的问题及其解决方案
- 普元 EOS Platform 7.6 sso集成业务应用实现单点登录,但登录跳转到成功页面时,经常出现闪屏问题,每秒10次以上
- 加密、解密、openssl的基本应用及CA的实现过程
- C++中的类模板应用问题