九度OJ 1544 数字序列区间最小值
题目地址:http://ac.jobdu.com/problem.php?pid=1544
- 题目描述:
-
给定一个数字序列,查询任意给定区间内数字的最小值。
- 输入:
-
输入包含多组测试用例,每组测试用例的开头为一个整数n(1<=n<=100000),代表数字序列的长度。
接下去一行给出n个数字,代表数字序列。数字在int范围内。
下一行为一个整数t(1<=t<=10000),代表查询的次数。
最后t行,每行给出一个查询,由两个整数表示l、r(1<=l<=r<=n)。
- 输出:
-
对于每个查询,输出区间[l,r]内的最小值。
- 样例输入:
-
5
3 2 1 4 3
3
1 3
2 4
4 5
- 样例输出:
-
1
1
3
An <O(N), O(sqrt(N))> solution
#include <stdio.h>
#include <math.h>
#include <limits.h> void Preprocess (int arr[], int n, int loc[]){
int i, j, k;
int step;
int min; step = (int)sqrt((double)n);
i = j = k = 0;
while (1){
min = k*step;
for (j=k*step+1; j<n && j<(k+1)*step; ++j){
if (arr[min] > arr[j])
min = j;
}
loc[k] = min;
++k;
if (j >= n)
break;
}
} int main(void){
int n;
int arr[100001];
int loc[1000];
int t;
int i;
int left;
int right;
int min;
int step;
int index; while (scanf ("%d", &n) != EOF){
step = (int)sqrt((double)n);
for (i=0; i<n; ++i){
scanf ("%d", &arr[i]);
}
Preprocess (arr, n, loc);
scanf ("%d", &t);
while (t-- != 0){
scanf ("%d%d", &left, &right);
--left;
--right;
min = INT_MAX;
while (left <= right && left % step != 0){
if (arr[left] < min){
min = arr[left];
}
++left;
}
while (left + step <= right){
index = loc[left/step];
if (arr[index] < min){
min = arr[index];
}
left += step;
}
while (left <= right){
if (arr[left] < min){
min = arr[left];
}
++left;
}
printf ("%d\n", min);
}
} return 0;
}
/**************************************************************
Problem: 1544
User: 简简单单Plus
Language: C
Result: Accepted
Time:330 ms
Memory:1252 kb
****************************************************************/
Sparse Table (ST) algorithm
//Sparse Table (ST) algorithm
#include <stdio.h>
#include <math.h>
#include <limits.h> #define MAX 100000
#define LOGMAX 20 void Preprocess (int M[MAX][LOGMAX], int arr[MAX], int n){
int i, j; for (i = 0; i < n; ++i)
M[i][0] = i;
for (j = 1; 1 << j <= n; ++j){
for (i = 0; i + (1 << j) - 1 < n; ++i){
if (arr[M[i][j - 1]] < arr[M[i + (1 << (j - 1))][j - 1]])
M[i][j] = M[i][j - 1];
else
M[i][j] = M[i + (1 << (j - 1))][j - 1];
}
}
} int main(void){
int n;
int arr[MAX];
int M[MAX][LOGMAX];
int test;
int left;
int right;
int i;
int min;
int k; while (scanf ("%d", &n) != EOF){
for (i = 0; i < n; ++i){
scanf ("%d", &arr[i]);
}
Preprocess (M, arr, n);
scanf ("%d", &test);
while (test-- != 0){
scanf ("%d%d", &left, &right);
--left;
--right;
k = 0;
while ((1 << (k + 1)) < (right - left + 1))
++k;
if (arr[M[left][k]] <= arr[M[right - (1 << k) + 1][k]])
min = arr[M[left][k]];
else
min = arr[M[right - (1 << k) + 1][k]]; printf ("%d\n", min);
}
} return 0;
}
/**************************************************************
Problem: 1544
User: 简简单单Plus
Language: C
Result: Accepted
Time:270 ms
Memory:9040 kb
****************************************************************/
Segment trees
#include <stdio.h>
#include <math.h> #define MAX 100000
#define MAXN 200000 void Initialize (int node, int b, int e, int M[MAXN], int arr[MAX], int n){
if (b == e){
M[node] = b;
}
else{
//compute the values in the left and right subtrees
Initialize(2 * node, b, (b + e) / 2, M, arr, n);
Initialize(2 * node + 1, (b + e) / 2 + 1, e, M, arr, n);
//search for the minimum value in the first and
//second half of the interval
if (arr[M[2 * node]] <= arr[M[2 * node + 1]])
M[node] = M[2 * node];
else
M[node] = M[2 * node + 1];
}
} int Query(int node, int b, int e, int M[MAXN], int arr[MAX], int i, int j)
{
int p1, p2; //if the current interval doesn't intersect
//the query interval return -1
if (i > e || j < b)
return -1; //if the current interval is included in
//the query interval return M[node]
if (b >= i && e <= j)
return M[node]; //compute the minimum position in the
//left and right part of the interval
p1 = Query(2 * node, b, (b + e) / 2, M, arr, i, j);
p2 = Query(2 * node + 1, (b + e) / 2 + 1, e, M, arr, i, j); //return the position where the overall
//minimum is
if (p1 == -1)
//return M[node] = p2;
return p2;
if (p2 == -1)
//return M[node] = p1;
return p1;
if (arr[p1] <=arr[p2])
return p1;
return p2;
} int main(void){
int n;
int arr[MAX];
int M[MAXN];
int t;
int left;
int right;
int i;
int index; while (scanf ("%d", &n) != EOF){
for (i = 0; i < n; ++i){
scanf ("%d", &arr[i]);
}
for (i=0; i<MAXN; ++i){
M[i] = -1;
}
Initialize (1, 0, n - 1, M, arr, n);
scanf ("%d", &t);
while (t-- != 0){
scanf ("%d%d", &left, &right);
--left;
--right;
index = Query(1, 0, n - 1, M, arr, left, right);
printf ("%d\n", arr[index]);
}
} return 0;
}
/**************************************************************
Problem: 1544
User: 简简单单Plus
Language: C
Result: Accepted
Time:290 ms
Memory:2016 kb
****************************************************************/
参考资料:http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor
http://dongxicheng.org/structure/lca-rmq/
http://dongxicheng.org/structure/segment-tree/
九度OJ 1544 数字序列区间最小值的更多相关文章
- [Jobdu] 题目1544:数字序列区间最小值
题目描述: 给定一个数字序列,查询任意给定区间内数字的最小值. 输入: 输入包含多组测试用例,每组测试用例的开头为一个整数n(1<=n<=100000),代表数字序列的长度.接下去一行给出 ...
- 九度OJ 1349 数字在排序数组中出现的次数 -- 二分查找
题目地址:http://ac.jobdu.com/problem.php?pid=1349 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数 ...
- 九度OJ 1077 最大序列和 -- 动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1077 题目描述: 给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”. 对 ...
- 九度OJ 1251:序列分割 (DFS)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:166 解决:34 题目描述: 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值 比如{3,2,4,3,6} 可以分成{ ...
- 九度oj 1349 数字在排序数组中出现的次数
原题链接:http://ac.jobdu.com/problem.php?pid=1349 二分.. #include<algorithm> #include<iostream> ...
- 九度OJ,题目1089:数字反转
题目描述: 12翻一下是21,34翻一下是43,12+34是46,46翻一下是64,现在又任意两个正整数,问他们两个数反转的和是否等于两个数的和的反转. 输入: 第一行一个正整数表示测试数据的个数n. ...
- 九度oj题目1009:二叉搜索树
题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...
- 【九度OJ】题目1074:对称平方数 解题报告
[九度OJ]题目1074:对称平方数 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1074 题目描述: 打印所有不超过n( ...
- 【九度OJ】题目1431:Sort 解题报告
[九度OJ]题目1431:Sort 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1431 题目描述: 给你n个 ...
随机推荐
- JS定时执行,循环执行
从http://www.jb51.net/article/23863.htm 转载 Document自带的方法: 循环执行:var timeid = window.setInterval(“方法名或 ...
- 并发容器之ConcurrentSkipListSet
概要 本章对Java.util.concurrent包中的ConcurrentSkipListSet类进行详细的介绍.内容包括:ConcurrentSkipListSet介绍ConcurrentSki ...
- 为FaceBook审核提交模拟器包及自己验证模拟器包
为FaceBook审核提交模拟器包及自己验证模拟器包折腾了一番,因为我的项目是用cocoapods管理的,所以跟普通直接运行name.xcodeproj项目有所不同. 切入正题 1.先设置 relea ...
- Python标准库10 多进程初步 (multiprocessing包)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经见过了使用subprocess包来创建子进程,但这个包有两个很大的局限性: ...
- 漫谈刑事辩护 z
各位律师,各位助理: 大家好!今天的律师沙龙由我来给大家谈一谈刑事辩护方面的问题.这次我谈的,主要是我这么多年来办理刑事案件,从事刑事辩护中的一些体会. 刑事辩护,大家最关心的莫过于收费问题了.我认为 ...
- [ActionScript 3.0] AS3实现滤镜叠加效果
import flash.display.BitmapData; import flash.filters.BlurFilter; import flash.geom.ColorTransform; ...
- 日期选择控件-laydate
laydate控件非常简单易用,只需要调用一个个函数就可以轻松实现日期时间选择. <%@ page language="java" import="java.uti ...
- aria-expanded,aria-hidden到底做什么用?
aria-expanded表示展开状态.默认为undefined, 表示当前展开状态未知.其它可选值:true表示元素是展开的:false表示元素不是展开的. aria-hidden字符串.可选值为t ...
- sql server Geometry 类型操作 笔记
sqlGeometry 类型为sql server 2008之后的版本 新加的一种CLR扩展数据类型,为广大sql server开发人员存储几何类型及空间运算提供极大的便利,下面说明geometry类 ...
- Python的方法分类
1.Python的类方法,实例方法,和静态方法 class S(object): def Test(self): print("TEST") @classmethod#类方法 de ...