Jump and Treasure (单调队列优化DP+调和级数)

题目大意: 

一个数列,每一次可以跳P以内的距离,数列是有正有负,问跳到后面去的最大值,  有Q次询问,问 leve i, 每次只能跳 i 的倍数,  n 10^6, q为 10^6次放

  • 由简单到困难的思想
  • 先考虑 leve 1的情况
  • 显然这个东西可以用单调队列优化DP
  • 而其他leve k可以 要弄的数 n/k个
  • 更具查询来做是要爆的
  • 预处理出

 (调和级数)

 

     就行了

后记:

  • 单调队列: 一个队列存是单调的, 而且开头是在那个范围内,并且 加入数的时候,如果比后面的优,就进去,并且要删除后面的数,应为他比后面的数在后面,一定是比他们更在那个范围内
  • 时间复杂度: 每一个数只会进队出队1次 是 O(n)的
  • 调和级数 复杂度是 nlogn

 

#include <bits/stdc++.h>
using namespace std;
#define M 2000005
#define ri register int 

int n,m;
int p[M];
int qu[M];
int main(){ 
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    scanf("%d%d",&n,&m);
    for(ri i=1;i<=n;i++) scanf("%d",&p[i]);
    int l=1,r=1;qu[1]=1;cout<<0<<endl;
    for(ri i=2;i<=n;i++)
    {
        while(qu[l]<i-m) l++;
                处理:
        while(p[qu[r]]>=p[i]&&r>=l) r--;qu[++r]=i;(插入)
    }
    
    
    
} 
View 单调队列

 

posted @ 2022-08-02 11:19  VxiaohuanV  阅读(88)  评论(0编辑  收藏  举报