• luoguP1440 求m区间内的最小值


    emmmmmm

    看到这道题的第一反应嘛

    (区间最小,大概是RMQ吧

    然后,华丽丽的80分

    (题解说st表会T两个点,可是我是MLE emmmm。。。

    貌似st表不能做,有一个滚动数组的优化,可以看看题解学一下

    这里我改用了单调队列的做法

    (本来用的STL的队列,但是学长说不方便,开一个数组即可 [而且我STL队列还没写出来23333

    emmmm(不知道怎么讲

    看代码吧

    #include<cstdio>
    using namespace std;
    
    const int maxn = 2000010;
    
    int q[maxn][2];//q[maxn][0]记录数,[1]记录输入的次序
    
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        printf("0
    ");//第一个前面没有数,提前输出0比较方便
        int head = 0,tail = 0;
        scanf("%d",&q[tail][0]);
        tail++;
        for(int i = 1;i < n;i++){
            if(i - q[head][1] > m)//每次循环判断是否是前m个数
            head ++;//不是的话指针后移,弹出一位
            printf("%d
    ",q[head][0]);//输出当前的最小值,第一次循环即为第一个数
            int x;
            scanf("%d",&x);
            while(tail > head && x < q[tail - 1][0])//判断输入的这个数是不是最小的
            tail --;//尾指针前移,当前值覆盖上一个比该值大的值
            q[tail][0] = x;//压入队列
            q[tail][1] = i;
            tail++;//保证队列不为空
        }
        return 0;
    }

    然后就没有然后啦

    最后放一下80分代码

    假装是把st表的模版题题解放上来了,就不写st表模版的题解了emmmm

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    #define maxn 2000005
    
    int dp[maxn][20];
    int n,m;
    int a[maxn],b[maxn];
    
    void RMQ(){
      for(int i = 1;i <= n;i++)
        dp[i][0] = a[i];//初始化
      for(int j = 1;(1 << j) <= n;j++)
        for(int i = 1;i <= n - (1 << j) + 1;i++)
          dp[i][j] = min(dp[i][j - 1],dp[i + (1 << (j - 1))][j - 1]);//状态转移方程
      int x = 0;
      for(int i = 1;i <= n;i++){
        if((1 << (x + 1)) <= i) x++;
        b[i] = x;//提前预处理每段区间长度的log,保证完全O(n)
      }
    }
    
    int query(int L,int R){
      int k = b[R - L + 1];
      return min(dp[L][k],dp[R - (1 << k) + 1][k]);//询问
    }
    
    int main(){
      scanf("%d%d",&n,&m);
      for(int i = 1;i <= n;i++)
        scanf("%d",&a[i]);
      RMQ();
      for(int i = 1;i <= n;i++){
        if(i == 1){
          printf("0
    ");
          continue;
        }
        else if(i == 2){
          printf("%d
    ",a[1]);
          continue;
        }//提前输出两个确定值
        int L = i - m;
        if(i - m <= 0)L = 1;//特判
        int R = i - 1;
        printf("%d
    ",query(L,R));
      }
      return 0;
    }

    zyr学长讲的太好了!!!

    他tql!!!
    %%%(放blog地址膜一下

    我听完了觉得自己不可能讲的那么清楚于是就不讲了吧233333

  • 相关阅读:
    Java 注解
    java多线程
    webstorm配置Monokai-Sublime.jar主题
    express
    npm与package.json
    Node require方法加载规则
    js伪数组转数组
    node中的Console
    Node.js核心模块-url
    服务端渲染SSR和客户端渲染CSR
  • 原文地址:https://www.cnblogs.com/sevenyuanluo/p/10057918.html
Copyright © 2020-2023  润新知