zoukankan      html  css  js  c++  java
  • 题目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

     1 #include <stdio.h>
     2 #include <math.h>
     3  
     4  
     5 #define N 100001
     6  
     7 #define max(a,b) a>b?a:b
     8 #define min(a,b) a<b?a:b
     9  
    10 int array[N];
    11 int RMQ_min[N][20];
    12 int RMQ_max[N][20];
    13  
    14  
    15 void RMQ(int n)
    16 {
    17     int i;
    18     int j;
    19  
    20     for(i = 1; i <= n; i++)
    21     {
    22         RMQ_min[i][0] = RMQ_max[i][0] = array[i];
    23     }
    24  
    25     double limit = log((double)n)/log(2.0);
    26  
    27     for(j = 1 ; j <= (int)limit; j++)
    28         for(i = 1; i + (1 << j) -1 <= n; i++)
    29         {
    30             RMQ_max[i][j] = max(RMQ_max[i][j-1], RMQ_max[i+(1<<(j-1))][j-1]);
    31             RMQ_min[i][j] = min(RMQ_min[i][j-1], RMQ_min[i+(1<<(j-1))][j-1]);
    32         }
    33  
    34 }
    35  
    36 int Max(int a, int b)
    37 {
    38     int k = (int)(log((double)(b-a+1))/log(2.0));
    39     return max(RMQ_max[a][k],RMQ_max[b-(1<<k)+1][k]);
    40 }
    41  
    42 int Min(int a, int b)
    43 {
    44     int k = (int)(log((double)(b-a+1))/log(2.0));
    45     return min(RMQ_min[a][k],RMQ_min[b-(1<<k)+1][k]);
    46 }
    47  
    48  
    49 int main()
    50 {
    51  
    52     int n;
    53     int i;
    54     int j;
    55     int t;
    56     int a;
    57     int b;
    58     int T[10001];
    59     int TT;
    60  
    61     while(scanf("%d",&n) != EOF)
    62     {   
    63         for(i = 1 ; i <= n; i++)
    64         {
    65             scanf("%d",array+i);
    66         }
    67  
    68         RMQ(n);
    69  
    70         j = 1;
    71         scanf("%d",&t);
    72         TT = t;
    73  
    74         while( t-- )
    75         {
    76             scanf("%d%d",&a, &b);
    77             T[j++] = Min(a,b);
    78         }
    79  
    80         for(i = 1 ;i <= TT; i++)
    81         {
    82             printf("%d
    ",*(T+i));
    83         }
    84     }
    85  
    86     return 0;
    87 }
  • 相关阅读:
    LA 6621 /ZOJ 3736 Pocket Cube 打表+暴力
    UVA 10273
    UVA 10158 并查集的经典应用
    CodeForces 382B 数学推导
    UVA 10806 最小费用最大流
    UVA 10330 最大流
    图论:匹配与覆盖+独立集 团与支配集
    sdut oj 操作系统实验--SSTF磁盘调度算法【操作系统算法】
    【转载】单调队列学习
    poj 3006 Dirichlet's Theorem on Arithmetic Progressions【素数问题】
  • 原文地址:https://www.cnblogs.com/chchche/p/3466023.html
Copyright © 2011-2022 走看看