[Jobdu] 题目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

RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。

主要方法及复杂度如下:

1、朴素(即搜索),O(n)-O(qn) online。

2、线段树,O(n)-O(qlogn) online。

3、ST(实质是动态规划),O(nlogn)-O(q) online。

ST算法(Sparse Table),以求最大值为例,设d[i,j]表示[i,i+2^j-1]这个区间内的最大值,那么在询问到[a,b]区间的最大值时答案就是max(d[a,k], d[b-2^k+1,k]),其中k是满足2^k<=b-a+1(即长度)的最大的k,即k=[ln(b-a+1)/ln(2)]。

d的求法可以用动态规划,d[i, j]=max(d[i, j-1],d[i+2^(j-1), j-1])。

4、RMQ标准算法:先规约成LCA(Lowest Common Ancestor),再规约成约束RMQ,O(n)-O(q) online。

首先根据原数列,建立笛卡尔树,从而将问题在线性时间内规约为LCA问题。LCA问题可以在线性时间内规约为约束RMQ,也就是数列中任意两个相邻的数的差都是+1或-1的RMQ问题。约束RMQ有O(n)-O(1)的在线解法,故整个算法的时间复杂度为O(n)-O(1)。

下面是方法3的实现:

 1 #include <climits>
 2 #include <cmath>
 3 #include <cstdio>
 4 #include <iostream>
 5 using namespace std;
 6
 7 int n, t;
 8 int l, r;
 9 int dp[100001][32];
10
11 void init() {
12     for (int j = 1; (1<<j) <= n; ++j) {
13         for (int i = 1; i + (1<<j) - 1 <= n; ++i) {
14             dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
15         }
16     }
17 }
18
19 void getRes() {
20     int k = (int) (log((double)(r-l+1))/log(2.0));
21     int res =  min(dp[l][k], dp[r-(1<<k)+1][k]);
22     printf("%d\n", res);
23 }
24
25 int main() {
26     while (scanf("%d", &n) != EOF) {
27         for (int i = 1; i <= n; ++i) {
28             scanf("%d", &dp[i][0]);
29         }
30         init();
31         scanf("%d", &t);
32         for (int i= 0; i < t; ++i) {
33             scanf("%d %d", &l, &r);
34             getRes();
35         }
36     }
37     return 0;
38 }
39 /**************************************************************
40     Problem: 1544
41     User: hupo250
42     Language: C++
43     Result: Accepted
44     Time:320 ms
45     Memory:14068 kb
46 ****************************************************************/
时间: 2024-11-07 00:48:18

[Jobdu] 题目1544:数字序列区间最小值的相关文章

[Jobdu] 题目1337:寻找最长合法括号序列

题目描述: 给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配:所有的右括号都有唯一的左括号匹配.例如:((()))()()便是一个长度为10的合法括号序列,而(()))( 则不是. 需要你求解的是,找出最长的合法括号子序列的长度,同时找出具有这样长度的序列个数. 输入: 测试数据包括多个,每个测试数据包含两行: 第一行为一个整数N,其中N不会超过10^6. 第二行为一个长度为N的字

【bzoj1049】【HAOI2006】【数字序列】

1049: [HAOI2006]数字序列 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1117 Solved: 454 [Submit][Status][Discuss] Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. Input 第一行包含一个数n,接下来n个整数按顺序描述每一项的键值. Output 第一行一个整数表示

BZOJ 1049 数字序列(LIS)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1049 题意:给出一个数列A,要求:(1)修改最少的数字使得数列严格递增:(2)在(1)的基础上使得修改的绝对值之和最小. 思路:对于第一问看起来像是求最长上升子 列,其实不是.我们想,若对于i<j,j能由i转移过来,那么需满足A[j]-A[i]>=j-i才行,这样我们发现只要A[j]-j& gt;=A[i]-i即可.因此令A[i]=A[i]-i,这样求LIS即可.对于第二问,

求一组数字序列的分布情况(java)

最近需要做一个正态分布的函数图像所以要处理一段double序列 写了这个算法  先上效果图: 核心思想: 1先根据步长计算每一个区间 2循环进行判断序列中每个数属于哪个区间 3用一个数组来保存每一个区间中 数的个数 这样就可以得到整个分布函数了 当然效率值得考虑 我的机器1百万以上的数据就会有问题了 这是一个double类型的例子 int型就更容易啦 上代码! 1 package com.huang.distribution; 2 3 import java.math.BigDecimal; 4

区间最小值 线段树 (2015年 JXNU_ACS 算法组暑假第一次周赛)

区间最小值 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 12   Accepted Submission(s) : 5 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 给定一个数字序列,查询随意给定区间内数字的最小值. Input

区间最小值(2) (线段树 更新区间)2015年 JXNU_ACS 算法组暑假第一次周赛

区间最小值(2) Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 26   Accepted Submission(s) : 9 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 给定一个数字序列以及一些操作,查询任意给定区间内数字的最小

codevs 2622 数字序列

2622 数字序列 提交地址:http://codevs.cn/problem/2622/ 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定一个长度为n的一个序列A1,A2,…,An,求序列中连续子序列的最大和. 例如:当输入为-5,3,5,7,-15,6,9,27,-36,10时,连续子序列6,9,27的和为42是最大值:而当序列变成-5,3,5,8,-15,6,9,27,-36,10时,连续子序列3,5,8,-15,6,9

【BZOJ 1049】 [HAOI2006]数字序列

1049: [HAOI2006]数字序列 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 979  Solved: 389 [Submit][Status] Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. Input 第一行包含一个数n,接下来n个整数按顺序描述每一项的键值. Output 第一行一个整数表示最少需要改变多少

找出数组中最长的连续数字序列(JavaScript实现)

原始题目: 给定一个无序的整数序列, 找最长的连续数字序列. 例如: 给定[100, 4, 200, 1, 3, 2], 最长的连续数字序列是[1, 2, 3, 4]. 小菜给出的解法: 1 function maxSequence(array,step){ 2 var _array = array.slice(), //clone array 3 _step = 1, 4 _arrayTemp = [], 5 i = 0; 6 7 var parseLogic = { 8 //result c