POJ - 3264 Balanced Lineup 线段树解RMQ
这个题目是一个典型的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的更多相关文章
- poj 3264 Balanced Lineup(线段树、RMQ)
题目链接: http://poj.org/problem?id=3264 思路分析: 典型的区间统计问题,要求求出某段区间中的极值,可以使用线段树求解. 在线段树结点中存储区间中的最小值与最大值:查询 ...
- POJ 3264 Balanced Lineup 线段树RMQ
http://poj.org/problem?id=3264 题目大意: 给定N个数,还有Q个询问,求每个询问中给定的区间[a,b]中最大值和最小值之差. 思路: 依旧是线段树水题~ #include ...
- [POJ] 3264 Balanced Lineup [线段树]
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 34306 Accepted: 16137 ...
- POJ 3264 Balanced Lineup 线段树 第三题
Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line ...
- 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 ...
- 【POJ】3264 Balanced Lineup ——线段树 区间最值
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 34140 Accepted: 16044 ...
- Poj 3264 Balanced Lineup RMQ模板
题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...
- POJ 3264 Balanced Lineup -- RMQ或线段树
一段区间的最值问题,用线段树或RMQ皆可.两种代码都贴上:又是空间换时间.. RMQ 解法:(8168KB 1625ms) #include <iostream> #include < ...
- POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 53703 Accepted: 25237 ...
随机推荐
- 在Vivado中调用ModelSim生成FSM的状态转移图
如果我们已经书写了一段FSM代码,现在想倒过来把它转换成为状态转移图,方便我们直观地检查我们书写的状态对不对(在写论文什么的画图太麻烦的时候,有个自动生成的是多方便啊!),应该怎么弄呢?通过在Viva ...
- Spring MVC 3.0 返回JSON数据的方法
Spring MVC 3.0 返回JSON数据的方法1. 直接 PrintWriter 输出2. 使用 JSP 视图3. 使用Spring内置的支持// Spring MVC 配置<bean c ...
- DAG模型——嵌套矩阵
有向无环图上的动态规划是学习动态规划的基础,很多问题都可以转化为DAG上的最长路.最短路或路径计数问题. 嵌套矩阵 有n个矩阵,每个矩阵可以用两个整数a,b描述,表示它的长和宽.矩阵X(a,b)可以嵌 ...
- C#语言之“string格式的日期时间字符串转为DateTime类型”的方法(转)
原文链接:http://www.cnblogs.com/Pickuper/articles/2058880.html 方法一:Convert.ToDateTime(string) string格式有要 ...
- (转)Libevent(2)— event、event_base
转自:http://name5566.com/4198.html 参考文献列表:http://www.wangafu.net/~nickm/libevent-book/ 此文编写的时候,使用到的 Li ...
- ubuntu nginx 伪静态 设置
简单的静态设置 1 vim nginx.conf // 修改nginx配置文件 server { .... root /usr/local/nginx/html; #nginx网站根目录 #下面这个 ...
- c语言位运算符
C语言既具有高级语言的特点,又具有低级语言的功能. 所谓位运算是指进行二进制位的运算. C语言提供的位运算: 运算符 含义 & 按位与 | 按位或 ∧ 按位异或 ∽ ...
- 采用python获得并修改文件编码(原创)
windows和linux采用了不同的编码,这让很多人伤透了脑经,这里我采用了Python的chardet库获得代码的编码,然后修改编码. 1.首先需要安装chardet库,有很多方式,我才用的是比较 ...
- CakePHP采用model的save方法更新数据所需查询
采用model的save方法更新数据所需查询 1. 验证时候要确认是update 或者 create,以便使用对应规则 public $validate = array( 'field_name' = ...
- mongodb3.2系统性学习——2、write concern mongodb 写安全机制
为了尊重作者原文章位置:http://kyfxbl.iteye.com/blog/1952941 首先讲一下mongodb 的写操作过程: mongodb有一个write concern的设置,作用是 ...