题目链接:
给出一个有N个数的序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,最大的数是多少。
例如: 1 7 6 3 1。i = 1, j = 3,对应的数为7 6 3,最大的数为7。(该问题也被称为RMQ问题)
Input
第1行:1个数N,表示序列的长度。(2 <= N <= 10000)
第2 - N + 1行:每行1个数,对应序列中的元素。(0 <= S[i] <= 10^9)
第N + 2行:1个数Q,表示查询的数量。(2 <= Q <= 10000)
第N + 3 - N + Q + 2行:每行2个数,对应查询的起始编号i和结束编号j。(0 <= i <= j <= N - 1)
Output
共Q行,对应每一个查询区间的最大值。
Input示例
5
1
7
6
3
1
3
0 1
1 3
3 4
Output示例
7
7
3
线段树学习入门:http://blog.csdn.net/x314542916/article/details/7837276
线段树相关题型:http://blog.csdn.net/yrhsilence/article/details/5793699
<span style="font-size:24px;">#include"stdio.h"
#include"stdlib.h"
#include"math.h"
#include"algorithm"
#include"iostream"
#include"string.h"
const int maxn=10000+5;
int maxv[maxn*3];
int data[maxn];
int n;
int max(int a,int b)
{ return a>b?a:b;}
void build(int node,int begin,int end)
{
if(begin==end)
maxv[node]=data[begin];
else{
int m=(begin+end)/2;
build(2*node,begin,m); //建立左子树
build(2*node+1,m+1,end);//建立右子树
if(maxv[2*node]>=maxv[2*node+1])
maxv[node]=maxv[2*node];
else
maxv[node]=maxv[2*node+1];
}
}
int query(int k,int L,int R,int ql,int qr)
{
if(ql<=L&&R<=qr)
return maxv[k];
int m=L+(R-L)/2; //左子树的区间右继 eg:(1 8) 左(1 4) 右(5 8) 求的结果是 4
int ans=-1;
if(ql<=m) ans=max(ans,query(k*2,L,m,ql,qr));
if(qr>m) ans=max(ans,query(k*2+1,m+1,R,ql,qr));
return ans;
}
void Updata(int k,int L,int R,int p,int v) //修改data[p]=v
{
int m=L+(R-L)/2;
if(L==R) maxv[k]=v; //只有一个节点,叶子节点
else
{
//L<R 先递归更新左子树
if(p<=m)
Updata(k*2,L,m,p,v);
else
Updata(k*2+1,m+1,R,p,v);
maxv[k]=max(maxv[k*2],maxv[k*2+1]);
}
}
void print()
{
for(int i=1;i<2*n;i++)
printf("%d ",maxv[i]);
printf("\n");
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&data[i]);
build(1,0,n-1);
int T;
scanf("%d",&T); //T次查询
while(T--)
{
int ql,qr;
scanf("%d%d",&ql,&qr);
printf("%d\n",query(1,0,n-1,ql,qr));
}
return 0;
} </span>
RMQ
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 10010;
int dp[MAXN][20];
int mm[MAXN];
//初始化RMQ, b数组下标从1开始,从0开始简单修改
void initRMQ(int n,int b[])
{
mm[0] = -1;
for(int i = 1; i <= n; i++)
{
mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
dp[i][0] = b[i];
}
for(int j = 1; j <= mm[n]; j++)
for(int i = 1; i + (1<<j) -1 <= n; i++)
dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
//查询最大值
int rmq(int x,int y)
{
int k = mm[y-x+1];
return max(dp[x][k],dp[y-(1<<k)+1][k]);
}
int main()
{
int n;
int b[MAXN];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",b+i);
initRMQ(n,b);
int m;scanf("%d",&m);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
int ans=rmq(x+1,y+1);
printf("%d\n",ans);
}
return 0;
}