Light oj 1082 - Array Queries 【RMQ 裸题】

1082 - Array Queries
Time Limit: 3 second(s)Memory Limit: 64 MB

Given an array with N elements, indexed from 1 to N. Now you will be given some queries in the form I J, your task is to find the minimum value from index I toJ.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

The first line of a case is a blank line. The next line contains two integers N (1 ≤ N ≤ 105)q (1 ≤ q ≤ 50000). The next line contains N space separated integers forming the array. There integers range in [0, 105].

The next q lines will contain a query which is in the form I J (1 ≤ I ≤ J ≤ N).

Output

For each test case, print the case number in a single line. Then for each query you have to print a line containing the minimum value between index I and J.

Sample Input

Output for Sample Input

2

 

5 3

78 1 22 12 3

1 2

3 5

4 4

 

1 1

10

1 1

Case 1:

1

3

12

Case 2:

10

Note

Dataset is huge. Use faster I/O methods.


PROBLEM SETTER: JANE ALAM JAN


题意:给你一个N个数组成的序列和Q次查询。每次查询区间[x,,y]最小值。


RMQ裸题,因为犯二RE了一次。。。


AC代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#define MAXN 100000+10
#define MAXM 2000+10
#define INF 0x3f3f3f3f
using namespace std;
int Amin[MAXN][30];
int A[MAXN];
int N, Q;
void RMQ_init()
{
    for(int i = 1; i <= N; i++)
        Amin[i][0] = A[i];
    for(int j = 1; (1<<j) <= N; j++)
    {
        for(int i = 1; i + (1<<j)-1 <= N; i++)
            Amin[i][j] = min(Amin[i][j-1], Amin[i+(1<<(j-1))][j-1]);
    }
}
int query(int L, int R)
{
    int k = 0;
    while((1<<(k+1)) <= R-L+1) k++;
    return min(Amin[L][k], Amin[R-(1<<k)+1][k]);
}
int k = 1;
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &N, &Q);
        for(int i = 1; i <= N; i++)
            scanf("%d", &A[i]);
        RMQ_init();
        int a, b;
        printf("Case %d:\n", k++);
        while(Q--)
        {
            scanf("%d%d", &a, &b);
            printf("%d\n", query(a, b));
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值