您的位置:首页 > 其它

线段树实现RMQ问题(线段树模板的基本应用)

2011-10-20 19:10 363 查看
RMQ问题如果用线段树实现的话,可以实现O(nlogN)的预处理,O(logN)的查询,速度还可以。

以求最大值为例,将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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: