• st表求区间最大值


    Input

    第一行给出一个数字N,接下来N+1行,每行给出一个数字Ai,(0<=i<=N<=1E6)
    接来给出一个数字Q(Q<=7000),代表有Q个询问
    每组询问格式为a,b即询问从输入的第a个数到第b个数,其中的最大值是多少

    Output

    如题所述

    Sample Input

    10
    0
    1
    2
    3
    2
    3
    4
    3
    2
    1
    0
    5
    0 10
    2 4
    3 7
    7 9
    8 8
    

    Sample Output

    4
    3
    4
    3
    2

    这题就怎么说呢,范围怎么大,暴力显然超时,st表表示起来也简单,就是一直把一个区间分成两块,求两块的最大值再比较(怎么那么像区间dp),然后这种划分又要用到倍增,就需要二进制,所以理解起来还是有一定的难度(有dp的预处理)

    代码:

     1 #include<cmath>
     2 #include<iostream>
     3 using namespace std;
     4 char ch; bool ok;
     5 void read(int &x){
     6     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     7     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     8     if (ok) x=-x;
     9 }
    10 int a[1000001],n,m,f[1000001][21],x,y,now;
    11 void st(int n)
    12 {
    13      for(int j=1;j<=20;j++)    
    14         for(int i=0;i<=n;i++)
    15             if(i+(1<<j)-1<=n)
    16                 f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    17 }
    18 int main()
    19 {
    20     read(n);
    21     for(int i=0;i<=n;i++)
    22         read(a[i]);
    23     for(int i=1;i<=n;i++)
    24         f[i][0]=a[i];
    25     st(n);
    26     read(m);
    27     for(int i=1;i<=m;i++)
    28     {
    29         read(x),read(y);
    30         now=(int)(log(y-x+1)/log(2));
    31         printf("%d
    ",max(f[x][now],f[y-(1<<now)+1][now]));
    32     }
    33 }
  • 相关阅读:
    二 、异常
    Java的基本概念
    Oracle case when
    oracle exists
    一 、前言
    location
    HTTP1.1初识
    数学学习笔记(持续更新中)
    [NOIP2017 提高组] 列队 题解
    [NOI2019] 回家路线 题解
  • 原文地址:https://www.cnblogs.com/lcxer/p/9441714.html
Copyright © 2020-2023  润新知