这个题目是一个典型的RMQ问题,给定一个整数序列,1~N,然后进行Q次询问,每次给定两个整数A,B,(1<=A<=B<=N),求给定的范围内,最大和最小值之差。

解法一:这个是最初的解法,时间上可能会超时,下面还有改进算法.4969ms

 #include<stdio.h>
#include<stdlib.h>
#define INF 1000010
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a)) typedef struct res
{
int mx,mi;
} pair; typedef struct node
{
struct node *lc,*rc;
int ld,rd;
pair res;
} node; node *buildTree(int a,int b)
{
node*p=(node*)malloc(sizeof(node));
p->ld=a;
p->rd=b;
p->res.mx=;
p->res.mi=INF;
p->lc=p->rc=NULL;
if(a==b)
return p;
p->lc=buildTree(a,(a+b)>>);
p->rc=buildTree(((a+b)>>)+,b);
return p;
} void insert(node*T,int pos,int key)
{
int mid=(T->rd+T->ld)>>;
if(T->rd==T->ld)
{
T->res.mx=T->res.mi=key;
return;
}
if(pos<=mid)
insert(T->lc,pos,key);
else insert(T->rc,pos,key);
T->res.mx=max(T->lc->res.mx,T->rc->res.mx);
T->res.mi=min(T->lc->res.mi,T->rc->res.mi);
return;
} pair search(node*T,int a,int b)
{
pair temp1,temp2,ans;
int mid=(T->rd+T->ld)>>; temp1.mx=temp2.mx=;
temp1.mi=temp2.mi=INF;
if(a<=T->ld&&T->rd<=b)
return T->res;
if(a<=mid)
temp1=search(T->lc,a,b);
if(b>mid)
temp2=search(T->rc,a,b);
ans.mx=max(temp1.mx,temp2.mx);
ans.mi=min(temp1.mi,temp2.mi);
return ans;
} int main(void)
{
int n,q,i,a,b;
pair ans;
scanf("%d%d",&n,&q);
node *head=buildTree(,n);
for(i=; i<=n; i++)
{
scanf("%d",&a);
insert(head,i,a);
}
for(i=; i<=q; i++)
{
scanf("%d%d",&a,&b);
ans=search(head,a,b);
printf("%d\n",ans.mx-ans.mi);
}
return ;
}

解法二:

利用数组的形式:3704ms

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 1000010
#define INF 1000010
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a)) int l[N],r[N],i,n;
typedef struct
{
int mx,mi;
} pair;
pair res[N]; void BuildTree(int x,int y,int p)
{
l[p]=x;
r[p]=y;
if(x==y)
return;
BuildTree(x,(x+y)>>,*p);
BuildTree(((x+y)>>)+,y,*p+);
} void Insert(int num,int p)
{
int mid=(l[p]+r[p])>>;
res[p].mx=max(res[p].mx,num);
res[p].mi=min(res[p].mi,num);
if(l[p]==r[p])
return;
if(i<=mid)
Insert(num,*p);
else Insert(num,*p+);
} pair search(int x,int y,int p)
{
pair a1,a2,ans;
a1.mx=a2.mx=;
a1.mi=a2.mi=INF;
int mid=(l[p]+r[p])>>;
if(x<=l[p]&&y>=r[p])
return res[p];
if(x<=mid)
a1=search(x,y,*p);
if(y>mid)
a2=search(x,y,*p+);
ans.mx=max(a1.mx,a2.mx);
ans.mi=min(a1.mi,a2.mi);
return ans;
} int main(void)
{
int q,j,x,y;
pair ans;
memset(res,,sizeof(res));
scanf("%d%d",&n,&q);
BuildTree(,n,);
for(i=; i<N; i++)
res[i].mi=INF;
for(i=; i<=n; i++)
{
scanf("%d",&j);
Insert(j,);
} for(i=; i<q; i++)
{
scanf("%d%d",&x,&y);
ans=search(x,y,);
printf("%d\n",ans.mx-ans.mi);
}
return ;
}

解法三:

这是利用别人的算法改进而来,所以有时候多借鉴别人的代码,并且可以和自己的想法结合起来,效果还不错.

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 50010
#define INF 1000010
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a)) typedef struct
{
int l,r;
int mx,mi;
} pair;
pair temp[N*];
int Max,Min; void BuildTree(int x,int y,int p)
{
temp[p].l=x;
temp[p].r=y;
temp[p].mx=;
temp[p].mi=INF;
if(x==y)
return;
int mid=(x+y)/;
BuildTree(x,mid,p*);
BuildTree(mid+,y,*p+);
} void Insert(int v,int num,int p)
{
if(temp[v].l==temp[v].r)
{
temp[v].mx=temp[v].mi=num;
return ;
}
int mid=(temp[v].r+temp[v].l)/;
if(p<=mid)
{
Insert(*v,num,p);
temp[v].mx=max(temp[v].mx,temp[*v].mx);
temp[v].mi=min(temp[v].mi,temp[*v].mi);
}
else
{
Insert(*v+,num,p);
temp[v].mx=max(temp[v].mx,temp[*v+].mx);
temp[v].mi=min(temp[v].mi,temp[*v+].mi);
}
} void search(int x,int y,int p)
{
if(temp[p].l==x&&temp[p].r==y)
{
Max=max(Max,temp[p].mx);
Min=min(Min,temp[p].mi);
return;
}
int mid=(temp[p].l+temp[p].r)/;
if(x>mid)
{
search(x,y,*p+);
}
else if(y<=mid)
{
search(x,y,*p);
}
else
{
search(x,mid,*p);
search(mid+,y,*p+);
}
return;
} int main(void)
{
int n,q,i,x,y;
scanf("%d%d",&n,&q);
BuildTree(,n,);
for(i=;i<=n;i++)
{
scanf("%d",&x);
Insert(,x,i);
}
for(i=;i<q;i++)
{
scanf("%d%d",&x,&y);
Max=;
Min=INF;
search(x,y,);
printf("%d\n",Max-Min);
}
return ;
}

POJ - 3264 Balanced Lineup 线段树解RMQ的更多相关文章

  1. poj 3264 Balanced Lineup(线段树、RMQ)

    题目链接: http://poj.org/problem?id=3264 思路分析: 典型的区间统计问题,要求求出某段区间中的极值,可以使用线段树求解. 在线段树结点中存储区间中的最小值与最大值:查询 ...

  2. POJ 3264 Balanced Lineup 线段树RMQ

    http://poj.org/problem?id=3264 题目大意: 给定N个数,还有Q个询问,求每个询问中给定的区间[a,b]中最大值和最小值之差. 思路: 依旧是线段树水题~ #include ...

  3. [POJ] 3264 Balanced Lineup [线段树]

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34306   Accepted: 16137 ...

  4. POJ 3264 Balanced Lineup 线段树 第三题

    Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line ...

  5. POJ 3264 Balanced Lineup (线段树)

    Balanced Lineup For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the s ...

  6. 【POJ】3264 Balanced Lineup ——线段树 区间最值

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34140   Accepted: 16044 ...

  7. Poj 3264 Balanced Lineup RMQ模板

    题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...

  8. POJ 3264 Balanced Lineup -- RMQ或线段树

    一段区间的最值问题,用线段树或RMQ皆可.两种代码都贴上:又是空间换时间.. RMQ 解法:(8168KB 1625ms) #include <iostream> #include < ...

  9. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

随机推荐

  1. 7.Composer的安装和使用

    1.安装Composer: 局部安装 要真正获取 Composer,我们需要做两件事.首先安装 Composer (同样的,这意味着它将下载到你的项目中): curl -sS https://getc ...

  2. Verilog HDL常用的行为仿真描述语句

    一.循环语句 1.forever语句 forever语句必须写在initial模块中,主要用于产生周期性波形. 2.利用for.while循环语句完成遍历 for.while语句常用于完成遍历测试.当 ...

  3. Servlet相关接口和Servlet的生命周期

    http://www.cnblogs.com/luotaoyeah/p/3860292.html Servlet相关接口和Servlet的生命周期 创建一个Servlet类最直接的方式是实现javax ...

  4. 10个你可能不知道的JavaScript小技巧

    1.变量转换 看起来很简单,但据我所看到的,使用构造函数,像Array()或者Number()来进行变量转换是常用的做法.始终使用原始数据类型(有时也称为字面量)来转换变量,这种没有任何额外的影响的做 ...

  5. JS实现rgb与16进制颜色相互转换

    1.rgb转16进制 function to16 (a) {//RGB(204,204,024) //十六进制颜色值的正则表达式 var reg = /^#([0-9a-fA-f]{3}|[0-9a- ...

  6. Xcode7 Xcode6 中添加pch文件

    在Xcode7 和 Xcode6 中添加.pch文件是一样的,具体操作图文如下: 第一步:在Xcode的项目里,一般在Supporting Files 文件夹下创建,选中Supporting File ...

  7. java新手笔记15 多态

    1.Animal类 package com.yfs.javase; public class Animal { public void cry() { System.out.println(" ...

  8. 《sort帮你排序》-linux命令五分钟系列之二十六

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  9. javascript 写策略模式,商场收银打折优惠策略

    [Decode error - output not utf-8] ----------------------------- 购物清单 方便面 : 100 x 50 = 5000 | 4000 菊花 ...

  10. 操作系统和Python的发展历程

    一:操作系统的发展历史: 操作系统:什么是操作系统?我们首先想到的是电脑,,也就是所谓的Windows8,Windows7,或者XP系统和Windows10,当然也包括我们手机的安卓系统或者IPhon ...